Python 3.10+: Optional[Type] or Type | None
Oct 4
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?
1 answer
Accepted answer · original discussion
Oct 4
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+.
The typing.python.org "Typing Best Practices" page says:
Where possible, use shorthand syntax for unions instead of
UnionorOptional.Noneshould be the last element of an union.
(The above statement first arrived in 2021)
3 question comments
Use comments to ask for clarification. Post a solution as an answer.
Oct 4
Jun 26
Jul 7
Optional was invented to indicate "type or None". It's intrinsic meaning is "type or None", so following good basic principles, using the type | None is more explicit. It also gets rid of an identifier. These are objective reasons for going with the new syntax as long as you're sure you've got the Python version to support it.