-
-
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
Fix make_simplified_union interaction with Any #2197
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -858,17 +858,18 @@ def make_simplified_union(items: List[Type], line: int = -1, column: int = -1) - | |
all_items.append(typ) | ||
items = all_items | ||
|
||
if any(isinstance(typ, AnyType) for typ in items): | ||
return AnyType() | ||
|
||
from mypy.subtypes import is_subtype | ||
removed = set() # type: Set[int] | ||
for i, ti in enumerate(items): | ||
if i in removed: continue | ||
# Keep track of the truishness info for deleted subtypes which can be relevant | ||
cbt = cbf = False | ||
for j, tj in enumerate(items): | ||
if i != j and is_subtype(tj, ti): | ||
# Attempt to only combine true subtypes by avoiding types containing Any. | ||
# TODO: Properly exclude generics and functions. | ||
tj_is_anylike = (isinstance(tj, AnyType) or | ||
(isinstance(tj, Instance) and tj.type.fallback_to_any)) | ||
if i != j and is_subtype(tj, ti) and not tj_is_anylike: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you check tj_is_anylike before is_subtype()? It seems perverse to call the latter when you know you're going to reject the result. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See also my comment #2031 (comment) for another potential improvement (though it wouldn't be consistent with preserving There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guido: I agree -- will swap the ordering. Jukka: I think it'd be better to fix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I've changed my mind. I don't feel strongly about this, but I think the conditional is moderately more readable if If you still prefer it otherwise, I'll switch it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't feel strongly either. I don't have any other objections, but I'll wait with merging this until it's clear what Jukka wanted. Or Jukka can merge. |
||
removed.add(j) | ||
cbt = cbt or tj.can_be_true | ||
cbf = cbf or tj.can_be_false | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -428,3 +428,10 @@ x + 1 | |
[out] | ||
main:2: note: In module imported here: | ||
tmp/a.py:3: error: Unsupported left operand type for + (some union) | ||
|
||
[case testOptionalFallbackToNone] | ||
from typing import Any, Optional | ||
class C(Any): | ||
pass | ||
x = None # type: Optional[C] | ||
x.foo() # E: Some element of union has no attribute "foo" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideas for additional test cases:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm missing something, but those test cases seem completely unrelated to this issue? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This introduces a new sort of union type (one with both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This actually doesn't introduce a new Union type. Explicitly writing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough, I remember seeing that at some point. Thus if things are broken, they were so already. I'll probably file a new issue -- some union-related code I browsed looked pretty suspicious. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was already an issue open for one of the bugs I was worried about: #1720 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if there are multiple
Any
types in the union to simplify? I think that we should remove duplicates away at least, perhaps by usingis_same_type
. SoUnion[Any, Any, int]
would be simplified intoUnion[Any, int]
.Edited