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 ran into this while trying to enable strict_equality on a codebase.
The problem is the last reveal_type call - Mypy claims the type is still Literal[E.ONE], but it's obviously Literal[E.TWO] (or at least E). If strict_equality is enabled, this will cause a type error when asserting in a test, for example.
Pyright doesn't seem to narrow here, claiming the type of a.a is E always.
I don't know what the correct answer is here. Maybe allow narrowing only on local variables? 🤷
Mypy version used: 1.10.1
Python version used: 3.8
The text was updated successfully, but these errors were encountered:
Yeah, this can be a problem. I'm tagging this as feature, since mypy is working "as designed", though here the behavior is not what is expected.
The narrowing behavior has been around for a very long time, but I think the situation got worse when mypy started narrowing enums on assignment. One option would be to experiment with less eagerly narrowing enums to literal types on attribute assignments/assertions/comparisons. Disabling narrowing of attribute access more widely may cause a lot of new errors, so we need to careful there.
Just to add another example (from aiohttp codebase):
if self._at_eof:
return b""
data = bytearray()
while not self._at_eof:
data.extend(await self.read_chunk(self.chunk_size))
if decode: # unreachable error here
return self.decode(data)
return data
Mypy thinks the code is unreachable because it has narrowed the attribute to False and thinks the loop will never exit.
I don't know how complex it'd be to implement, but I'm think the best approach could be to do the type narrowing, but anytime a method is called on that object, or an await happens to yield to the event loop, then the type narrowing should be reset.
So:
assert foo.bar is True
foo.bar # narrowed to True
foo.something()
foo.bar # bool again
I'm not super sure if this is a bug or not, but the behavior is different in Mypy and pyright so probably worth discussing it.
To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=3a34812b38b40ca5cb913ee48daf2c49
I ran into this while trying to enable
strict_equality
on a codebase.The problem is the last
reveal_type
call - Mypy claims the type is stillLiteral[E.ONE]
, but it's obviouslyLiteral[E.TWO]
(or at leastE
). If strict_equality is enabled, this will cause a type error when asserting in a test, for example.Pyright doesn't seem to narrow here, claiming the type of
a.a
isE
always.I don't know what the correct answer is here. Maybe allow narrowing only on local variables? 🤷
The text was updated successfully, but these errors were encountered: