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.
Answer from Bhargav Rao on Stack OverflowFrom 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.
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].
Videos
Hey guys
I often write functions where the wanted returned type is, let's say, bool, but it could also return None. The returned bool can be True, but it will never be False:
def is_odd(number):
if number % 2 == 0:
return True
print(is_odd(4))(obviously this function could have been written differently, like returning the evaluation directly, but it's an example of what could be long functions where this is not an option).
With type hinting, I know I can define multiple return types. But since I am looking for a bool value, and not so much the None value, what is the most Pythonic to type hint the function?
Should it always reflect all the possible returned types, including None, like this?
def is_odd(number: int) -> bool | None:
if number % 2 == 0:
return TrueOr is this okay?
def is_odd(number: int) -> bool:
if number % 2 == 0:
return True