-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Allow assignments to multiple targets from union types #4067
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
Changes from 1 commit
b89fc28
13cd547
d550e4a
f4b57eb
edd70cc
9a68ae6
012be52
1a34540
036af84
a4b734b
950b8f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1639,7 +1639,7 @@ def check_multi_assignment(self, lvalues: List[Lvalue], | |
def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: Expression, | ||
rvalue_type: UnionType, context: Context, | ||
infer_lvalue_type: bool) -> None: | ||
"""Check assignment to multiple lavlue targets when rvalue type is a Union[...]. | ||
"""Check assignment to multiple lvalue targets when rvalue type is a Union[...]. | ||
For example: | ||
|
||
t: Union[Tuple[int, int], Tuple[str, str]] | ||
|
@@ -1651,7 +1651,8 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E | |
inferred types for first assignments, 'assignments' contains the narrowed types | ||
for binder. | ||
""" | ||
transposed = tuple([] for _ in lvalues) # type: Tuple[List[Type], ...] | ||
transposed = tuple([] for _ in | ||
self.flatten_lvalues(lvalues)) # type: Tuple[List[Type], ...] | ||
# Notify binder that we want to defer bindings and instead collect types. | ||
with self.binder.accumulate_type_assignments() as assignments: | ||
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. Add comment about why we have this. |
||
for item in rvalue_type.items: | ||
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. Add short comment describing what we are doing here. For example, something like "Type check the assignment separately for each union item and collect the inferred lvalue types for each union item.". |
||
|
@@ -1660,10 +1661,7 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E | |
self.check_multi_assignment(lvalues, rvalue, context, | ||
infer_lvalue_type=infer_lvalue_type, | ||
rv_type=item, undefined_rvalue=True) | ||
for t, lv in zip(transposed, lvalues): | ||
if isinstance(lv, StarExpr): | ||
# Unwrap StarExpr, since it is unwrapped by other helpers. | ||
lv = lv.expr | ||
for t, lv in zip(transposed, self.flatten_lvalues(lvalues)): | ||
t.append(self.type_map.pop(lv, AnyType(TypeOfAny.special_form))) | ||
union_types = tuple(UnionType.make_simplified_union(col) for col in transposed) | ||
for expr, items in assignments.items(): | ||
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. Again, add comment that describes the purpose of this look in one sentence. |
||
|
@@ -1675,16 +1673,25 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E | |
UnionType.make_simplified_union(types), | ||
UnionType.make_simplified_union(declared_types), | ||
False) | ||
for union, lv in zip(union_ty 10000 pes, lvalues): | ||
for union, lv in zip(union_types, self.flatten_lvalues(lvalues)): | ||
# Properly store the inferred types. | ||
if isinstance(lv, StarExpr): | ||
lv = lv.expr | ||
_1, _2, inferred = self.check_lvalue(lv) | ||
if inferred: | ||
self.set_inferred_type(inferred, lv, union) | ||
else: | ||
self.store_type(lv, union) | ||
|
||
def flatten_lvalues(self, lvalues: List[Expression]) -> List[Expression]: | ||
res = [] # type: List[Expression] | ||
for lv in lvalues: | ||
if isinstance(lv, (TupleExpr, ListExpr)): | ||
res.extend(self.flatten_lvalues(lv.items)) | ||
if isinstance(lv, StarExpr): | ||
# Unwrap StarExpr, since it is unwrapped by other helpers. | ||
lv = lv.expr | ||
res.append(lv) | ||
return res | ||
|
||
def check_multi_assignment_from_tuple(self, lvalues: List[Lvalue], rvalue: Expression, | ||
rvalue_type: TupleType, context: Context, | ||
undefined_rvalue: bool, | ||
|
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.
Add docstring. Also mention that this is used for multi-assignment from union (and why this is needed there).