Python Type Hints - Make Mypy disallow implicit optional types
The original type hint proposal, PEP 484, initially allowed implicit optional types in function signatures. That is, a parameter with a default value of
None would have its type automatically interpreted as optional. For example, this signature:
def message(name: str = None) -> None: ...
…would be equivalent to allowing
None in the type:
def message(name: str | None = None) -> None: ...
That would be written
typing.Optional[str] with the old syntax.
Four years after its inception, a discussion lead to PEP 484 being changed to remove this feature. The Python precept “explicit is better than implicit” won out. The union types section of the PEP now ends:
A past version of this PEP allowed type checkers to assume an optional type when the default value is
This is no longer the recommended behavior. Type checkers should move towards requiring the optional type to be made explicit.
So now that first example should produce a type checking error, and you need to write the second version, with an explicit
| None in the type.
Althought this was a while ago in 2018, Mypy’s default configuration hasn’t caught up. As of version 0.982, Mypy still allows implicit optional types. But you can opt-in to disallowing them by enabling the
no_implicit_optional option, for example in
[tool.mypy] no_implicit_optional = true
Then, Mypy will report errors for every implicit optional type. If you then check that first example:
$ mypy example.py example.py:1: error: Incompatible default for argument "name" (default has type "None", argument has type "str") Found 1 error in 1 file (checked 1 source file)
The Mypy 0.981 release post announced turning this option on by default:
Implicit Optional Types Will Be Disabled by Default
A future mypy feature release (possibly the next one after 0.98x) will disable implicit optional types such as these by default, and they will have to be explicitly enabled…
It also promises to make migration easier:
We hope to provide a migration tool that will automatically switch implicit optional types to explicit ones in function signatures.
But if you are just starting out with type hints, or you have a relatively small project, I’d recommend enabling the option today. I do so on all my projects. Adding
| None to a few parameters is not that much work to be up-to-date with the standards.
Make your development more pleasant with Boost Your Django DX.
One summary email a week, no spam, I pinky promise.
- Python Type Hints - Old and new ways to write the same types
- Python Type Hints - How to Enable Postponed Evaluation With __future__.annotations
Tags: mypy, python