After a guard with isinstance, mypy should consider the variable to be of that type.
For example:
deff(x: A) ->None:
ifisinstance(x, B) andx.value:
passclassA:
passclassB(A):
value=0
Here, mypy reports that x doesn't have a field value. This can of course be solved with a cast, but that is annoying to type and clutters the code. At least in simple case, mypy could infer that x is of type B in the rhs of the and-statement and in the block following the if-statement.
This already works if the condition only has an isinstance check:
deff(x: A) ->None:
ifisinstance(x, B):
print(x.value) # OkclassA:
passclassB(A):
value=0
Mypy should support more cases, including and expressions (your example should be valid).
Here is another case that could be useful (this could be a separate issue):
deff(x: object) ->None:
ifisinstance(x, int) orisinstance(x, str): # or isinstance(x, (int, str))# type of x should be Union[int, str]pass
These improvements are important for proper type checking of None values (currently None is treated pretty much like null in Java, i.e. it is implicitly included in every type). For example, consider this code:
Just to put it out there, the Cobra approach (see Compile-time Nil Tracking) to null values seems nicer, in my opinion, than using Union[T, None]. Basically, it would mean something like this:
defx(a: Nullable[int]) ->int:
print(a*a) # ok; a is still an intreturna# error; cannot convert Nullable type to none-Nullable typeifa: returna# ok; a cannot be None
Just to put it out there, the Cobra http://cobra-language.com/docs/quality/ approach (see Compile-time Nil
Tracking) to null values seems nicer, in my opinion, than using Union[T,
None]. Basically, it would mean something like this:
def x(a: Nullable[int]) -> int:
print(a*a) # ok; a is still an int
return a # error; cannot convert Nullable type to none-Nullable type
if a: return a # ok; a cannot be None
—
Reply to this email directly or view it on GitHub #473 (comment).
@kirbyfan64 I agree, special syntax would be preferable. But I'm not sure why a*a should be okay if a has an optional type. None * None raises an exception.
The original program here has worked since commit 0b151c6. Also, Jukka's "another case" will be addressed by #1712, and the example with Union[int, None] already works under strict optional checking. So closing this as fixed.
Activity
JukkaL commented on Oct 12, 2014
This already works if the condition only has an isinstance check:
Mypy should support more cases, including and expressions (your example should be valid).
Here is another case that could be useful (this could be a separate issue):
These improvements are important for proper type checking of None values (currently None is treated pretty much like null in Java, i.e. it is implicitly included in every type). For example, consider this code:
Currently there is no error reported for the the second print statement.
JukkaL commented on Oct 12, 2014
Added related issues #475 and #476.
refi64 commented on Oct 12, 2014
Just to put it out there, the Cobra approach (see Compile-time Nil Tracking) to null values seems nicer, in my opinion, than using Union[T, None]. Basically, it would mean something like this:
gvanrossum commented on Oct 12, 2014
My preferred spelling would be Optional[int]. (Nullable reeks of SQL. :-)
On Sun, Oct 12, 2014 at 1:57 PM, Ryan Gonzalez notifications@github.com
wrote:
--Guido van Rossum (python.org/~guido)
refi64 commented on Oct 12, 2014
@gvanrossum You're very right; I like Optional better.
JukkaL commented on Oct 12, 2014
@kirbyfan64 I agree, special syntax would be preferable. But I'm not sure why a*a should be okay if a has an optional type. None * None raises an exception.
JukkaL commented on Oct 12, 2014
Added issue #477 for Optional[T].
rwbarton commented on Jun 15, 2016
The original program here has worked since commit 0b151c6. Also, Jukka's "another case" will be addressed by #1712, and the example with Union[int, None] already works under strict optional checking. So closing this as fixed.