Now that Python 3.10 has been released, is there any preference when indicating that a parameter or returned value might be optional, i.e., can be None. So what is preferred:
Option 1:
def f(parameter: Optional[int]) -> Optional[str]:
Option 2:
def f(parameter: int | None) -> str | None:
Also, is there any preference between Type | None and None | Type?
PEP 604 covers these topics in the specification section.
The existing
typing.Unionand|syntax should be equivalent.int | str == typing.Union[int, str]
The order of the items in the Union should not matter for equality.
(int | str) == (str | int) (int | str | float) == typing.Union[str, float, int]Optional values should be equivalent to the new union syntax
None | t == typing.Optional[t]
As @jonrsharpe comments, Union and Optional are not deprecated, so the Union and | syntax are acceptable.
Łukasz Langa, a Python core developer, replied on a YouTube live related to the Python 3.10 release that Type | None is preferred over Optional[Type] for Python 3.10+.
Non-authoritative, but I would expect Optional when
None)None would be unusual for the caller to passWhile I would expect some Union or | to be used when
NoneNone is also a valid valueSee related suggestions at How do I add default parameters to functions when using type hinting?
I would personally go with Option 2 moving forward.
Also, just wanted to add this for awareness, but Python 3.7+ can made to support this syntax using a __future__ import as shown below. This type checks just the same; I actually got the tip from the latest release notes from Pycharm, which I'm currently using.
from __future__ import annotations
def f(parameter: int | None) -> str | None:
...