Disabling strict optional checking
Mypy also has an option to treat None
as a valid value for everytype (in case you know Java, it’s useful to think of it as similar tothe Java null
). In this mode None
is also valid for primitivetypes such as int
and float
, and Optional
types arenot required.
The mode is enabled through the —no-strict-optional
command-lineoption. In mypy versions before 0.600 this was the default mode. Youcan enable this option explicitly for backward compatibility withearlier mypy versions, in case you don’t want to introduce optionaltypes to your codebase yet.
It will cause mypy to silently accept some buggy code, such asthis example – it’s not recommended if you can avoid it:
- def inc(x: int) -> int:
- return x + 1
- x = inc(None) # No error reported by mypy if strict optional mode disabled!
However, making code “optional clean” can take some work! You can also usethe mypy configuration file to migrate your codeto strict optional checking one file at a time, since there existsthe per-module flagstrict_optional
to control strict optional mode.
Often it’s still useful to document whether a variable can beNone
. For example, this function accepts a None
argument,but it’s not obvious from its signature:
- def greeting(name: str) -> str:
- if name:
- return 'Hello, {}'.format(name)
- else:
- return 'Hello, stranger'
- print(greeting('Python')) # Okay!
- print(greeting(None)) # Also okay!
You can still use Optional[t]
to document that None
is avalid argument type, even if strict None
checking is notenabled:
- from typing import Optional
- def greeting(name: Optional[str]) -> str:
- if name:
- return 'Hello, {}'.format(name)
- else:
- return 'Hello, stranger'
Mypy treats this as semantically equivalent to the previous exampleif strict optional checking is disabled, since None
is implicitlyvalid for any type, but it’s much moreuseful for a programmer who is reading the code. This also makesit easier to migrate to strict None
checking in the future.