4

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?

Cornel Masson
  • 1,352
  • 2
  • 17
  • 33
  • 3
    The type hint doesn't replace the default value. With just `b: Optional[str]` you actually still need to pass a value for `b` when calling the function. – deceze Apr 28 '22 at 07:45
  • 1
    In `def my_func(a, b: Optional[str])` `b` is **not** optional (but you _can_ explicitly pass `None`)! – jonrsharpe Apr 28 '22 at 07:49
  • Yeah, I just tested this after I wrote the post (face palm!). Semantically, I think it's a bit of hole in Python's typing system: typing a parameter as optional (using old or new pipe style) should really default the value to None. – Cornel Masson Apr 28 '22 at 08:04
  • Corrected with EDIT above. – Cornel Masson Apr 28 '22 at 08:15

1 Answers1

10

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.

Bharel
  • 23,672
  • 5
  • 40
  • 80
  • 3
    This refers to leaving out the None _type_, not the None _value_. You could never leave out the value (that changes the actual runtime behaviour, which type hints don't do). – jonrsharpe Apr 28 '22 at 23:02
  • 1
    @jon yup, it's the answer to the edited question but basically answers both at the same time. – Bharel Apr 29 '22 at 07:59