-
-
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
Strange behavior using Tagged Union #10659
Comments
It's not that mypy narrows the type incorrectly - it's just an imprecise error message: ...
# No narrowing occurs here since mypy does not understand this pattern
if instance_a.get("tag") == "A":
reveal_type(instance_a) # Revealed type is "Union[TaggedTypeA, TaggedTypeB]"
print(f"Am I type a this time? {instance_a['is_a']}") # TypedDict "TaggedTypeB" has no key "is_a" Compare this to accessing an attribute of union type: from typing import Union
class A:
a: int
b: bool
class B:
a: int
ab: Union[A, B] = A()
ab.b # Item "B" of "Union[A, B]" has no attribute "b" |
Thank you for the explanation. This error message makes sense given the context. Two follow up questions before I close this:
|
Since the upgrade to mypy 0.900 I'm also seeing this behavior while before the narrowing was working correctly. |
I would be willing to work on a pull request on this issue if someone could point me to where in the codebase is responsible for handling the transformation between union and specific types. |
@levrik if you're seeing a regression, please open another issue with your code. Previous mypy versions complain about the examples in this issue, so seems separate from what you're describing. As for implementing narrowing for tagged unions using Line 4348 in 3319826
|
@hauntsaninja I've opened #10764 for the issue I'm seeing. |
Bug Report
When using tagged unions, mypy infers correctly with with
instance["tag"]
,but fails with
instance.get("tag")
To Reproduce
tagged_union.py
:mypy tagged_union.py
Error occurs in second if statement
Expected Behavior
I can see that mypy correctly infers the type of
instance_a
when I useinstance_a["tag"] == "A"
(the first if expression).Therefore, I would expect the same behavior when using
instance_a.get("tag") == "A"
(the second if clause).Actual Behavior
mypy correctly infers the type of
instance_a
when I useinstance_a["tag"] == "A"
(the first if expression).mypy fails to infer the type when I use
instance_a.get("tag") == "A"
.In fact, mypy doesn't only not infer the correct type, it infers the opposite type
TaggedTypeB
which does not make sense at allYour Environment
mypy.ini
(and other config files): NoneThe text was updated successfully, but these errors were encountered: