Incorrect tracing of while True body in PyPy 3.8
PyPy 3.8 traces the body of a while True
differently than either PyPy 3.7 or CPython 3.8.
Running this code shows the problem:
import linecache, sys
def trace(frame, event, arg):
# The weird globals here is to avoid a NameError on shutdown...
if frame.f_code.co_filename == globals().get("__file__"):
lineno = frame.f_lineno
print("{} {}: {}".format(event[:4], lineno, linecache.getline(__file__, lineno).rstrip()))
return trace
print(sys.version)
sys.settrace(trace)
def wrong_bcd_bits(n: int):
while True:
d = n % 10
n = n // 10
for i in (1, 2):
yield bool(d & i)
print(list(zip(range(4), wrong_bcd_bits(36))))
PyPy 3.7 produces this output:
3.7.10 (51efa818fd9b, Apr 04 2021, 12:03:51)
[PyPy 7.3.4 with GCC Apple LLVM 12.0.0 (clang-1200.0.32.29)]
call 13: def wrong_bcd_bits(n: int):
line 14: while True:
line 15: d = n % 10
line 16: n = n // 10
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
call 18: yield bool(d & i)
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
call 18: yield bool(d & i)
line 17: for i in (1, 2):
line 15: d = n % 10 <******
line 16: n = n // 10
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
call 18: yield bool(d & i)
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
[(0, False), (1, True), (2, True), (3, True)]
PyPy 3.8 produces this:
3.8.12 (279d80ac2079, Oct 17 2021, 05:25:49)
[PyPy 7.3.6 with GCC Apple LLVM 13.0.0 (clang-1300.0.29.3)]
call 13: def wrong_bcd_bits(n: int):
line 15: d = n % 10
line 16: n = n // 10
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
call 18: yield bool(d & i)
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
call 18: yield bool(d & i)
line 17: for i in (1, 2):
line 16: n = n // 10 <******
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
call 18: yield bool(d & i)
line 17: for i in (1, 2):
line 18: yield bool(d & i)
retu 18: yield bool(d & i)
[(0, False), (1, True), (2, True), (3, True)]
Notice that when the loop on line 17 finishes, 3.7 then traces line 15 again, but 3.8 doesn't trace it (the starred lines). Is this expected?