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
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()
⇒ 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