You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We'd require an explicit optional argument type in cases like this:
deff(x: int=None) ->None:
...
Currently this is accepted by mypy, unless --no-implicit-optional is used. The idea would be to make --no-implicit-optional the default, and --implicit-optional can be used to get back to the current default behavior.
It might be a good idea to flip the switch sooner rather than later. If I understand things correctly, annotations relying on "implicit optional" are no longer PEP 484 compliant after python/peps#689 and the number of these non-compliant annotations will keep on increasing as long as mypy allows them.
@hukkinj1 A good point. We could try to get this included in the next public release as a breaking change, perhaps, if there no good arguments against this.
I was wondering if we could change the behavior to mean, "the argument is optional, but explicit None is not allowed". Here's a simple, contrived use-case:
classPoint:
...
@overloaddefupdate(self, other_point: Point) ->None: ...
@overloaddefupdate(self, *, x: int=None, y: int=None) ->None: ... # Keyword-only arguments that can't explicitly be `None`defupdate(self, *args: Any, **kwargs: Any) ->None:
ifargs:
self.x=args[0].xself.y=args[0].yelse:
self.x=kwargs.get("x", self.x) # Can't be `None` because explicit `.update(x=None)` is not allowedself.y=kwargs.get("y", self.y)
PEP 484 is clear that the subexpression x: int = None should be flagged as an error going forward.
An ellipsis is already the standard way to indicate this behavior within an overload signature: x: int = .... Or you can use the actual default value (x: int = 0).
What is the status of this almost 2 years in? Clearly foo(x: int = None) is more concise than foo(x: Optional[int] = None). While the latter may seem more correct than the former, the intent of the former is transparent for anyone understanding type hints. There are other situation in which brevity has been chosen over "correctness". For example None is allowed to be used instead of NoneType in unions.
Reacted by Vojtěch Oram, Tuukka Mustonen, Sam Bradshaw, Chris Withers, Andy MacKinlay, Daniel Darabos, Jannis Vajen, Alex Lokhman, Mohamed Elsabagh, Dan Morrison and 6 more
@hauntsaninja At this moment documentation reads "This was disabled by default" / "This was True by default" but does not explain why. Mypy does a better job, it emits note: PEP 484 prohibits implicit Optional.
I think it makes sense to add this sentence—PEP 484 prohibits implicit Optional—e.g. to
Activity
Disable implicit introduction of Optional via default parameter.
hukkin commentedon Nov 3, 2020
It might be a good idea to flip the switch sooner rather than later. If I understand things correctly, annotations relying on "implicit optional" are no longer PEP 484 compliant after python/peps#689 and the number of these non-compliant annotations will keep on increasing as long as mypy allows them.
JukkaL commentedon Nov 4, 2020
@hukkinj1 A good point. We could try to get this included in the next public release as a breaking change, perhaps, if there no good arguments against this.
cc @ilevkivskyi
lazytype commentedon Aug 17, 2021
I was wondering if we could change the behavior to mean, "the argument is optional, but explicit
Noneis not allowed". Here's a simple, contrived use-case:erictraut commentedon Aug 17, 2021
PEP 484 is clear that the subexpression
x: int = Noneshould be flagged as an error going forward.An ellipsis is already the standard way to indicate this behavior within an overload signature:
x: int = .... Or you can use the actual default value (x: int = 0).tzaffi commentedon May 9, 2022
What is the status of this almost 2 years in? Clearly
foo(x: int = None)is more concise thanfoo(x: Optional[int] = None). While the latter may seem more correct than the former, the intent of the former is transparent for anyone understanding type hints. There are other situation in which brevity has been chosen over "correctness". For exampleNoneis allowed to be used instead ofNoneTypein unions.Update git submodules
mypy: set no_implicit_optional
Use --no-implicit-optional by default
Use --no-implicit-optional for type checking
Use --no-implicit-optional for type checking
Use --no-implicit-optional for type checking
Use --no-implicit-optional for type checking
Use --no-implicit-optional for type checking
7 remaining items
Update git submodules
mypy: set no_implicit_optional
[fbsync] Use --no-implicit-optional for type checking (#6413)
Use --no-implicit-optional for type checking (psf#3220)
hauntsaninja commentedon Sep 8, 2022
If you're stumbling upon this, here is a codemod to help you automatically fix your code: https://github.com/hauntsaninja/no_implicit_optional
Use --no-implicit-optional by default (#13401)
Bump from upstream (#3)
Upstream force (#8)
sambacc: fixed mypy-0.990 errors
sambacc: fixed mypy-0.990 errors
Update type annotations for PEP 484
Enable no-implicit-optional and fix the one error that occurs
Enable no-implicit-optional and fix the one error that occurs (#2509)
andrei-korshikov commentedon Mar 6, 2025
@hauntsaninja At this moment documentation reads "This was disabled by default" / "This was True by default" but does not explain why. Mypy does a better job, it emits
note: PEP 484 prohibits implicit Optional.I think it makes sense to add this sentence—PEP 484 prohibits implicit Optional—e.g. to
mypy/docs/source/command_line.rst
Line 455 in b1ac028
and
mypy/docs/source/config_file.rst
Line 614 in b1ac028