Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
Closed
Description
Tracing an if-statement in an async-for seems to trace statements that aren't executed. It was correct in 3.9, became wrong in 3.10, and remains wrong in 3.11.
importlinecache,sysdeftrace(frame,event,arg):ifframe.f_code.co_filename==globals().get("__file__"):lineno=frame.f_linenoline=linecache.getline(__file__,lineno).rstrip()print("{} {}: {}".format(event[:4],lineno,line))returntraceprint(sys.version)sys.settrace(trace)importasyncioclassCoverMe:def__init__(self,number):self._number=numberasyncdef_async_range(self):forninrange(self._number):yieldnasyncdefdo_something(self):accumulated=0asyncforninself._async_range():accumulated+=nprint(f"{accumulated=}")ifaccumulated>10:breakreturnaccumulatedasyncdefmain():print(awaitCoverMe(10).do_something())asyncio.run(main())
Running this code with 3.11.0b1 gives:
3.11.0b1 (main, May 12 2022, 06:47:33) [Clang 12.0.0 (clang-1200.0.32.29)]call 15: class CoverMe:line 15: class CoverMe:line 16: def __init__(self, number):line 19: async def _async_range(self):line 23: async def do_something(self):retu 23: async def do_something(self):call 33: async def main():line 34: print(await CoverMe(10).do_something())call 16: def __init__(self, number):line 17: self._number = numberretu 17: self._number = numbercall 23: async def do_something(self):line 24: accumulated = 0line 25: async for n in self._async_range():call 19: async def _async_range(self):line 20: for n in range(self._number):line 21: yield nretu 21: yield nexce 25: async for n in self._async_range():line 26: accumulated += nline 27: print(f"{accumulated=}")accumulated=0line 28: if accumulated > 10:line 29: break <<<<line 25: async for n in self._async_range():call 21: yield nline 20: for n in range(self._number):line 21: yield nretu 21: yield nexce 25: async for n in self._async_range():line 26: accumulated += nline 27: print(f"{accumulated=}")accumulated=1line 28: if accumulated > 10:line 29: break <<<<line 25: async for n in self._async_range():call 21: yield nline 20: for n in range(self._number):line 21: yield nretu 21: yield nexce 25: async for n in self._async_range():line 26: accumulated += nline 27: print(f"{accumulated=}")accumulated=3line 28: if accumulated > 10:line 29: break <<<<line 25: async for n in self._async_range():call 21: yield nline 20: for n in range(self._number):line 21: yield nretu 21: yield nexce 25: async for n in self._async_range():line 26: accumulated += nline 27: print(f"{accumulated=}")accumulated=6line 28: if accumulated > 10:line 29: break <<<<line 25: async for n in self._async_range():call 21: yield nline 20: for n in range(self._number):line 21: yield nretu 21: yield nexce 25: async for n in self._async_range():line 26: accumulated += nline 27: print(f"{accumulated=}")accumulated=10line 28: if accumulated > 10:line 29: break <<<<line 25: async for n in self._async_range():call 21: yield nline 20: for n in range(self._number):line 21: yield nretu 21: yield nexce 25: async for n in self._async_range():line 26: accumulated += nline 27: print(f"{accumulated=}")accumulated=15line 28: if accumulated > 10:line 29: breakline 31: return accumulatedretu 31: return accumulatedexce 34: print(await CoverMe(10).do_something())15retu 34: print(await CoverMe(10).do_something())call 21: yield nexce 21: yield nretu 21: yield n
The lines marked with<<<<
show a break statement being traced when it is not executed.