Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8d12e3d

Browse files
author
Chetan Khanna
committed
defer assignment after all rhs evaluation is complete
1 parent 97828d9 commit 8d12e3d

2 files changed

Lines changed: 71 additions & 69 deletions

File tree

mypyc/irbuild/builder.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,8 @@ def process_iterator_tuple_assignment(
932932
split_idx = target.star_idx if target.star_idx is not None else len(target.items)
933933

934934
# Read values before the first starred value
935-
values = []
935+
left_values = []
936+
right_values = []
936937
for litem in target.items[:split_idx]:
937938
ritem = self.call_c(next_op, [iterator], line)
938939
error_block, ok_block = BasicBlock(), BasicBlock()
@@ -948,11 +949,7 @@ def process_iterator_tuple_assignment(
948949

949950
self.activate_block(ok_block)
950951

951-
values.append(ritem)
952-
953-
# Assign read values to target lvalues
954-
for litem, ritem in zip(target.items[:split_idx], values):
955-
self.assign(litem, ritem, line)
952+
left_values.append(ritem)
956953

957954
# Read the starred value and all values after it
958955
if target.star_idx is not None:
@@ -975,13 +972,15 @@ def process_iterator_tuple_assignment(
975972

976973
self.activate_block(ok_block)
977974

978-
values = []
979975
for litem in reversed(post_star_vals):
980976
ritem = self.primitive_op(list_pop_last, [iter_list], line)
981-
values.append(ritem)
977+
right_values.append(ritem)
982978

983-
# Assign the read values to target lvalues
984-
for litem, ritem in zip(reversed(post_star_vals), values):
979+
# Assign read values to target lvalues
980+
for litem, ritem in zip(target.items[:split_idx], left_values):
981+
self.assign(litem, ritem, line)
982+
983+
for litem, ritem in zip(reversed(post_star_vals), right_values):
985984
self.assign(litem, ritem, line)
986985

987986
# Assign the starred value
@@ -1003,6 +1002,10 @@ def process_iterator_tuple_assignment(
10031002
self.add(Unreachable())
10041003

10051004
self.activate_block(ok_block)
1005+
1006+
# Assign read values to target lvalues
1007+
for litem, ritem in zip(target.items[:split_idx], left_values):
1008+
self.assign(litem, ritem, line)
10061009

10071010
def push_loop_stack(self, continue_block: BasicBlock, break_block: BasicBlock) -> None:
10081011
self.nonlocal_control.append(

mypyc/test-data/irbuild-statements.test

Lines changed: 58 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,9 @@ def from_any(a):
445445
r2 :: bool
446446
r3 :: object
447447
r4 :: bool
448-
x, y, r5 :: object
448+
r5 :: object
449449
r6 :: bool
450+
x, y :: object
450451
L0:
451452
r0 = PyObject_GetIter(a)
452453
r1 = PyIter_Next(r0)
@@ -461,14 +462,14 @@ L3:
461462
r4 = raise ValueError('not enough values to unpack')
462463
unreachable
463464
L4:
464-
x = r1
465-
y = r3
466465
r5 = PyIter_Next(r0)
467466
if is_error(r5) goto L6 else goto L5
468467
L5:
469468
r6 = raise ValueError('too many values to unpack')
470469
unreachable
471470
L6:
471+
x = r1
472+
y = r3
472473
return 1
473474

474475
[case testMultiAssignmentCoercions]
@@ -506,9 +507,10 @@ def from_any(a):
506507
r2 :: bool
507508
r3 :: object
508509
r4 :: bool
509-
r5, x :: int
510-
y, r6 :: object
511-
r7 :: bool
510+
r5 :: object
511+
r6 :: bool
512+
r7, x :: int
513+
y :: object
512514
L0:
513515
r0 = PyObject_GetIter(a)
514516
r1 = PyIter_Next(r0)
@@ -523,15 +525,15 @@ L3:
523525
r4 = raise ValueError('not enough values to unpack')
524526
unreachable
525527
L4:
526-
r5 = unbox(int, r1)
527-
x = r5
528-
y = r3
529-
r6 = PyIter_Next(r0)
530-
if is_error(r6) goto L6 else goto L5
528+
r5 = PyIter_Next(r0)
529+
if is_error(r5) goto L6 else goto L5
531530
L5:
532-
r7 = raise ValueError('too many values to unpack')
531+
r6 = raise ValueError('too many values to unpack')
533532
unreachable
534533
L6:
534+
r7 = unbox(int, r1)
535+
x = r7
536+
y = r3
535537
return 1
536538

537539
[case testStarUnpack]
@@ -550,28 +552,27 @@ def f(a):
550552
r5 :: bool
551553
r6 :: object
552554
r7 :: bool
553-
r8 :: str
554-
r9 :: int32
555-
r10 :: bit
556-
r11 :: str
557-
r12 :: int32
558-
r13 :: bit
559-
r14 :: list
560-
r15 :: ptr
561-
r16 :: native_int
562-
r17 :: short_int
563-
r18 :: bit
564-
r19 :: bool
565-
r20, r21 :: object
566-
r22 :: str
567-
r23 :: int32
568-
r24 :: bit
569-
r25 :: str
570-
r26 :: int32
571-
r27 :: bit
572-
r28 :: str
573-
r29 :: int32
574-
r30 :: bit
555+
r8 :: list
556+
r9 :: native_int
557+
r10 :: short_int
558+
r11 :: bit
559+
r12 :: bool
560+
r13, r14 :: object
561+
r15 :: str
562+
r16 :: i32
563+
r17 :: bit
564+
r18 :: str
565+
r19 :: i32
566+
r20 :: bit
567+
r21 :: str
568+
r22 :: i32
569+
r23 :: bit
570+
r24 :: str
571+
r25 :: i32
572+
r26 :: bit
573+
r27 :: str
574+
r28 :: i32
575+
r29 :: bit
575576
L0:
576577
r0 = __main__.globals :: static
577578
r1 = 'it'
@@ -589,34 +590,32 @@ L3:
589590
r7 = raise ValueError('not enough values to unpack')
590591
unreachable
591592
L4:
592-
r8 = 'x'
593-
r9 = PyObject_SetAttr(a, r8, r4)
594-
r10 = r9 >= 0 :: signed
595-
r11 = 'y'
596-
r12 = PyObject_SetAttr(a, r11, r6)
597-
r13 = r12 >= 0 :: signed
598-
r14 = PySequence_List(r3)
599-
r15 = get_element_ptr r14 ob_size :: PyVarObject
600-
r16 = load_mem r15 :: native_int*
601-
keep_alive r14
602-
r17 = r16 << 1
603-
r18 = 4 <= r17 :: signed
604-
if r18 goto L6 else goto L5 :: bool
593+
r8 = PySequence_List(r3)
594+
r9 = var_object_size r8
595+
r10 = r9 << 1
596+
r11 = int_le 4, r10
597+
if r11 goto L6 else goto L5 :: bool
605598
L5:
606-
r19 = raise ValueError('not enough values to unpack')
599+
r12 = raise ValueError('not enough values to unpack')
607600
unreachable
608601
L6:
609-
r20 = CPyList_PopLast(r14)
610-
r21 = CPyList_PopLast(r14)
611-
r22 = 'w'
612-
r23 = PyObject_SetAttr(a, r22, r20)
613-
r24 = r23 >= 0 :: signed
614-
r25 = 'u'
615-
r26 = PyObject_SetAttr(a, r25, r21)
616-
r27 = r26 >= 0 :: signed
617-
r28 = 'z'
618-
r29 = PyObject_SetAttr(a, r28, r14)
619-
r30 = r29 >= 0 :: signed
602+
r13 = CPyList_PopLast(r8)
603+
r14 = CPyList_PopLast(r8)
604+
r15 = 'x'
605+
r16 = PyObject_SetAttr(a, r15, r4)
606+
r17 = r16 >= 0 :: signed
607+
r18 = 'y'
608+
r19 = PyObject_SetAttr(a, r18, r6)
609+
r20 = r19 >= 0 :: signed
610+
r21 = 'w'
611+
r22 = PyObject_SetAttr(a, r21, r13)
612+
r23 = r22 >= 0 :: signed
613+
r24 = 'u'
614+
r25 = PyObject_SetAttr(a, r24, r14)
615+
r26 = r25 >= 0 :: signed
616+
r27 = 'z'
617+
r28 = PyObject_SetAttr(a, r27, r8)
618+
r29 = r28 >= 0 :: signed
620619
return 1
621620

622621
[case testMultiAssignmentNested]

0 commit comments

Comments
 (0)