MyPy 'Optional' Modifier for Parameters with Default Value 'None'
For a Python function with a parameter with default value None
, what is the effect of marking that parameter as Optional
?
def f(a: Optional[str] = None)
seemed overly verbose to me, because I didn’t understand why “Optional” wouldn’t just be inferred from def f(a: str = None)
.
It turns out that, as of today, “Optional” is inferred in the second definition, such that the second def is equal to the first. However, there is [discussion about removing this implicit Optional’(]ttps://github.com/python/typing/issues/275). One key argument for the removal is that “inn all other contexts, a: int = None
is a type error.
I put together a small example of the differences between the two defs, when using the –strict-optional (which will eventually be default in mypy) and –no-implicit-optional flags for mypy:
# test.py
from typing import Optional
def foo(x: Optional[str]):
print(x)
foo(None)
foo()
def bar(y: Optional[str] = None):
print(y)
bar(None)
bar()
def baz(z: str = None):
print(z)
baz(None)
baz()
Results:
⇒ pipenv run mypy test.py
test.py:8: error: Too few arguments for "foo"
⇒ pipenv run mypy test.py --strict-optional # strict-optional will eventually be default for mypy
test.py:8: error: Too few arguments for "foo"
⇒ pipenv run mypy test.py --strict-optional --no-implicit-optional
test.py:8: error: Too few arguments for "foo"
test.py:16: error: Incompatible default for argument "z" (default has type "None", argument has type "str")
test.py:19: error: Argument 1 to "baz" has incompatible type "None"; expected "str"
⇒ pipenv run python --version
Python 3.4.7
⇒ pipenv run mypy --version
mypy 0.570