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
{{ message }}
Repository navigation
Declaring the existence of a variable while using --strict-optional #2179
test_computed_later.py:1: error: Incompatible types in assignment (expression has type None, variable has type "str")
In this program, the assignment computed_later = None is intended to be a declaration, as described in PEP 484 (Type Hints):
In stubs it may be useful to declare the existence of a variable without giving it an initial value. This can be done using a literal ellipsis:
from typing import IO
stream = ... # type: IO[str]
In non-stub code, there is a similar special case:
from typing import IO
stream = None # type: IO[str]
Type checkers should not complain about this (despite the value None not matching the given type), nor should they change the inferred type to Optional[...](despite the rule that does this for annotated arguments with a default value of None). The assumption here is that other code will ensure that the variable is given a value of the proper type, and all uses can assume that the variable has the given type.
It appears that --strict-optional is not treating the None-assignment as a declaration in this case, which is inconsistent with PEP 484. Thoughts?
Thanks for reporting this -- I think this is an area where mypy with --strict-optional is not yet compliant with PEP 484.
Note that if you place that code inside a class body, it will be accepted. (It's possible that this was intentional, this behavior is somewhat controversial.)
Yeah, this is definitely a place where mypy isn't PEP 484 compatible yet. I think it's worth implementing undefined checking before allowing this, because otherwise people won't be able to rely on non-Optional types really being non-Optional.
FWIW, the reason it works without any annotations is because mypy will do a limited sort of type inference on variables that are initially None, and because mypy will track the current type of unions. Here's what mypy is thinking linewise:
computed_later=None# computed_later is a partial None typecomputed_later='hello'# computed_later now has type Optional[str], but has type str in the current contextprint(computed_later)
I don't think we need to keep this open. Nothing will likely change in how mypy works with type comments and variable annotations will soon become the default way of things.
Activity
davidfstr commentedon Sep 24, 2016
For this particular example I was able to leave off the annotation to remove the error:
gvanrossum commentedon Sep 24, 2016
Thanks for reporting this -- I think this is an area where mypy with
--strict-optionalis not yet compliant with PEP 484.Note that if you place that code inside a class body, it will be accepted. (It's possible that this was intentional, this behavior is somewhat controversial.)
gvanrossum commentedon Sep 24, 2016
Also, for people reading this, there's a subtlety with the PEP that few appreciate. While it allows this:
it does not allow this:
IOW the initializer must be exactly the expression
None, not any value of typeNone. (Even though of course at runtime they are the same object.)The reason is that we really treat
as a special syntactic form, equivalent to PEP 526's initializer-less form:
ddfisher commentedon Sep 27, 2016
Yeah, this is definitely a place where mypy isn't PEP 484 compatible yet. I think it's worth implementing undefined checking before allowing this, because otherwise people won't be able to rely on non-Optional types really being non-Optional.
FWIW, the reason it works without any annotations is because mypy will do a limited sort of type inference on variables that are initially None, and because mypy will track the current type of unions. Here's what mypy is thinking linewise:
ilevkivskyi commentedon Jul 6, 2019
I don't think we need to keep this open. Nothing will likely change in how mypy works with type comments and variable annotations will soon become the default way of things.
jiridanek commentedon Oct 11, 2020
FFR, the PEP issue that lead to defining the special treatment of None was python/typing#61.
amirsoroush commentedon Apr 21, 2023
Up to this point(mypy=1.2.0 and Python=3.11) Mypy still doesn't allow this with either cases:
alexisdrakopoulos commentedon May 13, 2024
Is there any update on the best way to type hint delayed initialised variables?