-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type narrowing broken with dict items #18440
Comments
Thanks for the report! The first example is not a bug. Consider this example: def a(k: str, d: dict[str, int | str]):
if isinstance(d[k], str):
d[k] = 1
d[k].upper() # clearly a crash However, the second example is in fact a limitation: def b(k: str, d: dict[str, int|str]):
match d[k]:
case str(s):
print(s.upper())
case int(x):
print(x)
case unreachable:
assert_never(unreachable) # really not reachable |
And the second part happens because only calls are currently considered "special enough", and an IndexExpr is not a CallExpr: Lines 5272 to 5284 in 106f714
That was introduced in #16503. I guess it should be possible to rewrite that name generation logic to make it work with any expression, not only a simple call. |
@sterliakov: Cool, do you plan to extend "this hack"? I was starting to do it, but only have the test case so far: # flags: --warn-unreachable
from typing import Dict, Union
m: Dict[str, Union[int, str]]
k: str
match m[k]:
case str(s):
reveal_type(s) # N: Revealed type is "builtins.str"
case int(i):
reveal_type(i) # N: Revealed type is "builtins.int"
case u:
u
[builtins fixtures/dict.pyi] Feel free to take it, if this small snippet seems useful. |
@tyralla yep, I'll try to get this done soon. I think I can (at a reasonably low cost of just keeping a last_used_id per We can also try to extend this spaghetti one-by-one for call, index, tuple, list, ... expressions, but I don't think it's the most ergonomic solution. This id shouldn't ever leak to error messages, so IMO just |
Bug Report
When using a dict item, the type does not get narrowed.
To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=77cccd913f6c38a3536c4306c1439cf3
Expected Behavior
Both functions should typecheck.
Actual Behavior
A workaround with an intermediate variable typechecks without issues.
Your Environment
mypy.ini
(and other config files): NoneThe text was updated successfully, but these errors were encountered: