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
I'm currently adding annotations to a complex module, and even after resolving most of the mypy errors within the module I suspect there are still quite a few inaccurately typed functions due to corner-cases which will only be detected in code that uses the module in specific ways. I already have unittests for this module (written using pytest) that do precisely this, so type checking these would be the ideal way to check my annotations -- all-in-one static and runtime analysis.
It would go a long way to easing adoption if mypy raised errors on type assertions that it can detect are false. e.g.:
Bonus points for supporting the python unittest module's assert*() methods, but most people these days are using pytest and as a feature request it seems much easier and more useful to simply support assert.
Note that this is somewhat in conflict with #3603. Right now, mypy gives the empty type to i, so it should be trivial to implement. But if #3603 will be resolved (e.g. using intersection types) this issue will require mypy to track the precise type of a name, instead of an upper bound, which is not something that mypy is designed to do (or, IMHO, can be expected to do; The last line is possible to handle, but it is not a common case, and not supported today at all).
Currently mypy will assign i the empty type after the assert (and therefore will assume it is unreachable), since it does not have general intersection types; but as it is argued in (#3603) this is a false positive, since mypy does not consider multiple inheritance.
Mypy will consider the latter type "inferred", but otherwise it is the same.
However, you can try
a: str=foo()
And mypy will complain, if that's what you want. This is a kind of static assertion, as opposed to the dynamic assertion in your examples. I think this is closer to what you actually looking for.
Activity
elazarg commentedon Dec 16, 2017
Note that this is somewhat in conflict with #3603. Right now, mypy gives the empty type to
i, so it should be trivial to implement. But if #3603 will be resolved (e.g. using intersection types) this issue will require mypy to track the precise type of a name, instead of an upper bound, which is not something that mypy is designed to do (or, IMHO, can be expected to do; The last line is possible to handle, but it is not a common case, and not supported today at all).chadrik commentedon Dec 16, 2017
@elazarg I don't completely follow why
i = 0would be assigned the empty type, though I do understand why mypy cannot checkassert type(i) is str.Would this be possible to check correctly:
elazarg commentedon Dec 16, 2017
It is not the
i = 0statement, but the meet ofintandstrthat is empty.In your specific example, it is obviously possible to check correctly since you know
type(i) is int. But not in the following:Currently mypy will assign
ithe empty type after the assert (and therefore will assume it is unreachable), since it does not have general intersection types; but as it is argued in (#3603) this is a false positive, since mypy does not consider multiple inheritance.chadrik commentedon Dec 16, 2017
I see, so for some subclass of
intandstrtheassertwould be true.Is this also the case for returned types? e.g.:
If no, then the feature request -- generating an error when type analysis tells us the assert is false -- would still have validity.
elazarg commentedon Dec 16, 2017
Mypy will consider the latter type "inferred", but otherwise it is the same.
However, you can try
And mypy will complain, if that's what you want. This is a kind of static assertion, as opposed to the dynamic assertion in your examples. I think this is closer to what you actually looking for.
ilevkivskyi commentedon Jun 15, 2019
This is a duplicate of #2395
hauntsaninja commentedon Aug 3, 2022
There is now
typing.assert_typefor this