I have a function in python that can either return a bool
or a list
. Is there a way to specify the return types using type hints?
For example, is this the correct way to do it?
def foo(id) -> list or bool:
...
I have a function in python that can either return a bool
or a list
. Is there a way to specify the return types using type hints?
For example, is this the correct way to do it?
def foo(id) -> list or bool:
...
From the documentation - Union Type:
A union object holds the value of the
|
(bitwise or) operation on multiple type objects. These types are intended primarily for type annotations. The union type expression enables cleaner type hinting syntax compared totyping.Union
.
This use of |
was added in Python 3.10. Hence the proper way to represent more than one return data type is:
def foo(client_id: str) -> list | bool:
For earlier versions, use typing.Union
:
from typing import Union
def foo(client_id: str) -> Union[list, bool]:
But do note that typing is not enforced. Python continues to remain a dynamically-typed language. The annotation syntax has been developed to help during the development of the code prior to being released into production. As PEP 484 states, "no type checking happens at runtime."
>>> def foo(a: str) -> list:
... return "Works"
...
>>> foo(1)
'Works'
As you can see I am passing an int value and returning a str. However the __annotations__
will be set to the respective values.
>>> foo.__annotations__
{'return': <class 'list'>, 'a': <class 'str'>}
Please go through PEP 483 for more about Type hints. Also see What are type hints in Python 3.5??
Kindly note that this is available only for Python 3.5 and upwards. This is mentioned clearly in PEP 484.
from typeguard import typechecked
, then add @typechecked
on a new line before any function or class for which you want typing to be enforced. You may need to do pip install typeguard
for this to work.
Commented
Jan 30, 2023 at 17:59
Python 3.10 or newer: Use |
. Example for a function which takes a single argument that is either an int
or str
and returns either an int
or str
:
def func(arg: int | str) -> int | str:
# ^^^^^^^^^ ^^^^^^^^^
# type of arg return type
Python 3.5 - 3.9: Use typing.Union
:
from typing import Union
def func(arg: Union[int, str]) -> Union[int, str]:
# ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
# type of arg return type
For the special case of X | None
you can use Optional[X]
.
foo( bar: int )
and foo( bar ) -> int
Commented
Dec 6, 2021 at 20:38
|
, will it be compatible with prior Python versions (since type hinting is just a "hint")? Thanks.
TypeError
before, not a syntax error.
In case anyone landed here in search of "how to specify types of multiple return values?", use a tuple of [type_value1, ..., type_valueN]
.
In Python 3.9+:
def f() -> tuple[dict, str]:
a = {1: 2}
b = "hello"
return a, b
In earlier versions, use typing.Tuple
:
from typing import Tuple
def f() -> Tuple[dict, str]:
...
The statement def foo(client_id: str) -> list or bool:
when evaluated is equivalent to
def foo(client_id: str) -> list:
and will therefore not do what you want.
The native way to describe a "either A or B" type hint is Union (thanks to Bhargav Rao):
def foo(client_id: str) -> Union[list, bool]:
Or, starting with Python 3.10 and beyond, using the |
operator:
def foo(client_id: str) -> list | bool:
I do not want to be the "Why do you want to do this anyway" guy, but maybe having 2 return types isn't what you want:
If you want to return a bool to indicate some type of special error-case, consider using Exceptions instead. If you want to return a bool as some special value, maybe an empty list would be a good representation.
You can also indicate that None
could be returned with Optional[list]
|
operator doesn't work when I try to indicate I'm allowing my function to return both str
and None
(i.e. -> str | None
). In this case, I get TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
. Union
works properly, though.
Optional[X]