'Python 3.10 optional parameter: type union vs None default [duplicate]

It's not a huge issue, but as a matter of style, I was wondering about the best way to indicate optional function parameters...

Before type hints, it was like this for parameter b:

def my_func(a, b = None)

Before Python 3.10, using type hints:

def my_func(a, b: Optional[str])

With Python 3.10's lovely pipe-type notation (see PEP 604):

def my_func(a, b: str | None)

The latter seems the obvious choice of the three options, but I was wondering if this completely eliminates the need to specify the default None value, which would be:

def my_func(a, b: str | None = None)

EDIT: Thanks to @deceze and @jonrsharpe for pointing out that def my_func(a, b: str | None) would still require you to pass a value to b: you would explicitly have to pass None if you wanted that.

So, the most concise one that will work to ensure that b is optional (i.e. the caller does not have to pass a value at all) is:

def my_func(a, b: str = None)

Stylistically, incorporating explicit typing, is def my_func(a, b: str | None = None), i.e. explicit optional typing plus default None value, ever an option?



Solution 1:[1]

Per PEP-484:

A past version of this PEP allowed type checkers to assume an optional type when the default value is None, as in this code:

def handle_employee(e: Employee = None): ...

This is no longer the recommended behavior. Type checkers should move towards requiring the optional type to be made explicit.

So the official answer is no. You should specify ... | None = None for optional arguments.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bharel