Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
Bug report
Bug description:
Reproducer:
deffoo():a= [1,2,3]exhit=iter(a)for_inexhit:passa.append("this should'be in exhit")print(f"got{list(exhit)}, should be []")foo()foo()foo()foo()foo()foo()
Output:
got [], should be []got [], should be []got [], should be []got [], should be []got [], should be []got ["this should'be in exhit"], should be []Obviously, the last line is incorrect.
Output with aPYTHON_LLTRACE=2 env:
got [],shouldbe []got [],shouldbe []got [],shouldbe []got [],shouldbe []got [],shouldbe []Optimizingfoo (/home/eclips4/programming-languages/cpython/example.py:1)atbyteoffset421ADD_TO_TRACE:_START_EXECUTOR (0,target=21,operand=0x7f4646e59832)21:JUMP_BACKWARD(5)2ADD_TO_TRACE:_CHECK_VALIDITY_AND_SET_IP (0,target=21,operand=0x7f4646e59832)3ADD_TO_TRACE:_TIER2_RESUME_CHECK (0,target=21,operand=0)18:FOR_ITER_LIST(3)4ADD_TO_TRACE:_CHECK_VALIDITY_AND_SET_IP (0,target=18,operand=0x7f4646e5982c)5ADD_TO_TRACE:_ITER_CHECK_LIST (3,target=18,operand=0)6ADD_TO_TRACE:_GUARD_NOT_EXHAUSTED_LIST (3,target=18,operand=0)7ADD_TO_TRACE:_ITER_NEXT_LIST (3,target=18,operand=0)20:STORE_FAST(2)8ADD_TO_TRACE:_CHECK_VALIDITY_AND_SET_IP (0,target=20,operand=0x7f4646e59830)9ADD_TO_TRACE:_STORE_FAST (2,target=20,operand=0)21:JUMP_BACKWARD(5)10ADD_TO_TRACE:_CHECK_VALIDITY_AND_SET_IP (0,target=21,operand=0x7f4646e59832)11ADD_TO_TRACE:_JUMP_TO_TOP (0,target=0,operand=0)Createdaproto-traceforfoo (/home/eclips4/programming-languages/cpython/example.py:1)atbyteoffset36--length11Optimizedtrace (length10):0OPTIMIZED:_START_EXECUTOR (0,jump_target=7,operand=0x7f4646e59e80)1OPTIMIZED:_TIER2_RESUME_CHECK (0,jump_target=7,operand=0)2OPTIMIZED:_ITER_CHECK_LIST (3,jump_target=8,operand=0)3OPTIMIZED:_GUARD_NOT_EXHAUSTED_LIST (3,jump_target=9,operand=0)4OPTIMIZED:_ITER_NEXT_LIST (3,target=18,operand=0)5OPTIMIZED:_STORE_FAST_2 (2,target=20,operand=0)6OPTIMIZED:_JUMP_TO_TOP (0,target=0,operand=0)7OPTIMIZED:_DEOPT (0,target=21,operand=0)8OPTIMIZED:_EXIT_TRACE (0,exit_index=0,operand=0)9OPTIMIZED:_EXIT_TRACE (0,exit_index=1,operand=0)got ["this should'be in exhit"],shouldbe []
It's definitely related to this part of code:
Lines 1027 to 1033 ine4a97a7
| if (is_for_iter_test[opcode]) { | |
| /* Target the POP_TOP immediately after the END_FOR, | |
| * leaving only the iterator on the stack. */ | |
| intextended_arg=inst->oparg>255; | |
| int32_tnext_inst=target+1+INLINE_CACHE_ENTRIES_FOR_ITER+extended_arg; | |
| jump_target=next_inst+inst->oparg+1; | |
| } |
I guess the culprit is there. If we remove the_GUARD_NOT_EXHAUSTED_LIST fromis_for_iter_test, the problem will go away (although it can still be reproduced in other ways using other (range, tuple) iterators).
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux, macOS