This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Python 3.9 traces async for/else incorrectly
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Mark.Shannon, nedbat
Priority: normal Keywords: 3.9regression, patch

Created on 2021-07-13 11:29 by nedbat, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 27255 merged Mark.Shannon, 2021-07-20 09:06
Messages (5)
msg397393 - (view) Author: Ned Batchelder (nedbat) * (Python triager) Date: 2021-07-13 11:29
Python 3.9 traces this code incorrectly.  Note: 3.8 and 3.10 are correct, only 3.9 gets it wrong.

-----------------------------------
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

import asyncio

async def async_gen():
    yield 13

async def async_test():
    global a
    a = 17
    async for i in async_gen():
        print(i + 19)
    else:
        a = 21

print(sys.version)
sys.settrace(trace)

asyncio.run(async_test())
assert a == 21
----------------------------------

The starred line shows a trace of a statement that is not executed:

  3.9.6 (default, Jul 13 2021, 07:21:14)
  [Clang 12.0.0 (clang-1200.0.32.29)]
  call 15: async def async_test():
  line 17:     a = 17
  line 18:     async for i in async_gen():
  call 12: async def async_gen():
  line 13:     yield 13
  retu 13:     yield 13
  exce 18:     async for i in async_gen():
  line 19:         print(i + 19)
  32
  line 18:     async for i in async_gen():
  call 13:     yield 13
  retu 13:     yield 13
  exce 18:     async for i in async_gen():
* line 19:         print(i + 19)
  line 21:         a = 21
  retu 21:         a = 21
msg397394 - (view) Author: Ned Batchelder (nedbat) * (Python triager) Date: 2021-07-13 11:30
The corresponding coverage.py issue: https://github.com/nedbat/coveragepy/issues/1158
msg397846 - (view) Author: Ned Batchelder (nedbat) * (Python triager) Date: 2021-07-20 00:14
@lukasz.langa, I guess this 3.9 tracing bug should also be closed as wont-fix?
msg397862 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2021-07-20 08:23
We can fix this for 3.9. The fix to 3.10 was trivial and should port easily.
msg397864 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2021-07-20 09:07
Not quite trivial, but simple enough :)
History
Date User Action Args
2022-04-11 14:59:47adminsetgithub: 88787
2021-07-20 10:13:36lukasz.langasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2021-07-20 09:07:51Mark.Shannonsetmessages: + msg397864
2021-07-20 09:06:57Mark.Shannonsetkeywords: + patch
stage: patch review
pull_requests: + pull_request25800
2021-07-20 08:23:57Mark.Shannonsetmessages: + msg397862
2021-07-20 00:14:54nedbatsetmessages: + msg397846
2021-07-13 11:30:33nedbatsetmessages: + msg397394
2021-07-13 11:29:22nedbatcreate