-
Notifications
You must be signed in to change notification settings - Fork 0
[mypyc] Match evaluation order of multiple assignment from iterable (#793) #8
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
base: master
Are you sure you want to change the base?
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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -579,7 +579,8 @@ def process_iterator_tuple_assignment(self, | |||||||||||||
# This may be the whole lvalue list if there is no starred value | ||||||||||||||
split_idx = target.star_idx if target.star_idx is not None else len(target.items) | ||||||||||||||
|
||||||||||||||
# Assign values before the first starred value | ||||||||||||||
# Read values before the first starred value | ||||||||||||||
values = [] | ||||||||||||||
for litem in target.items[:split_idx]: | ||||||||||||||
ritem = self.call_c(next_op, [iterator], line) | ||||||||||||||
error_block, ok_block = BasicBlock(), BasicBlock() | ||||||||||||||
|
@@ -592,9 +593,13 @@ def process_iterator_tuple_assignment(self, | |||||||||||||
|
||||||||||||||
self.activate_block(ok_block) | ||||||||||||||
|
||||||||||||||
values.append(ritem) | ||||||||||||||
|
||||||||||||||
# Assign read values to target lvalues | ||||||||||||||
for litem, ritem in zip(target.items[:split_idx], values): | ||||||||||||||
self.assign(litem, ritem, line) | ||||||||||||||
Comment on lines
+598
to
600
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.
Comment on lines
+598
to
600
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. Two-Phase Assignment PatternThe code implements a clear two-phase pattern: first reading all values, then assigning them. This separation improves maintainability by making the execution order explicit and matching Python's evaluation semantics for unpacking assignments. Standards
|
||||||||||||||
|
||||||||||||||
# Assign the starred value and all values after it | ||||||||||||||
# Read the starred value and all values after it | ||||||||||||||
if target.star_idx is not None: | ||||||||||||||
Comment on lines
+602
to
603
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. Star Unpack TestingTest case for star unpacking exists but comment indicates implementation change. Ensure test coverage validates both reading and assignment phases for starred values. Standards
|
||||||||||||||
post_star_vals = target.items[split_idx + 1:] | ||||||||||||||
iter_list = self.call_c(to_list, [iterator], line) | ||||||||||||||
|
@@ -612,8 +617,13 @@ def process_iterator_tuple_assignment(self, | |||||||||||||
|
||||||||||||||
self.activate_block(ok_block) | ||||||||||||||
|
||||||||||||||
values = [] | ||||||||||||||
for litem in reversed(post_star_vals): | ||||||||||||||
ritem = self.call_c(list_pop_last, [iter_list], line) | ||||||||||||||
Comment on lines
+620
to
622
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. Post-Star Assignment OrderSimilar to the first issue, values after the starred expression are assigned immediately after reading, violating Python's evaluation-then-assignment order. The fix correctly reads all values first, then performs assignments separately. Standards
Comment on lines
+620
to
622
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. Redundant Value ProcessingValues are immediately assigned after being popped from the list, creating the same evaluation order issue as above. This pattern leads to inconsistent state if an exception occurs during iteration, causing performance overhead from unnecessary partial assignments that may need to be rolled back. Standards
|
||||||||||||||
values.append(ritem) | ||||||||||||||
|
||||||||||||||
# Assign the read values to target lvalues | ||||||||||||||
for litem, ritem in zip(reversed(post_star_vals), values): | ||||||||||||||
self.assign(litem, ritem, line) | ||||||||||||||
Comment on lines
+625
to
627
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.
Comment on lines
+625
to
627
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. Reversed Post-Star AssignmentThe post-star values are collected in reverse order (using list_pop_last), but the assignment loop also uses reversed(post_star_vals), causing double reversal. This incorrectly assigns values to the wrong variables compared to Python's expected behavior.
Suggested change
Standards
Comment on lines
+620
to
627
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. Inconsistent Pattern ImplementationThe code correctly implements the read-then-assign pattern for post-star values, but uses a different approach than for pre-star values. This inconsistency could lead to maintenance issues and potential bugs when modifying either section. The pattern should be consistently applied across both code paths. Standards
|
||||||||||||||
|
||||||||||||||
# Assign the starred value | ||||||||||||||
|
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.
Consider clarifying in the comment that the purpose of reading values first is to ensure correct evaluation order, matching Python semantics.