New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weirdness with traceback when resuming coroutines with coro.throw() #93592
Comments
A successful run of
the same
|
I should add that this is not specific to |
In which version(s) of Python does this happen? |
"CPython versions tested on: 3.10.4" I used to be a regular cpython contributor but haven't built cpython from source in some 8 years, so, I cannot really help you further with the core diagnostics. |
confirmed to exist in 3.7, 3.8, 3.9, 3.10. Fixed in 3.11 The following, short, test demonstrates the issue: import types
import traceback
async def a():
return await b()
async def b():
return await c()
@types.coroutine
def c():
try:
traceback.print_stack()
yield len(traceback.extract_stack())
except ZeroDivisionError:
traceback.print_stack()
yield len(traceback.extract_stack())
r = a()
print(r.send(None))
print(r.throw(ZeroDivisionError)) |
(cherry picked from commit 771eff2) Co-authored-by: Kristján Valur Jónsson <sweskman@gmail.com>
kristjanvalur commentedJun 7, 2022
•
edited
Bug report
When a coroutine is resumed using
coro.throw()
, e.g. by usingTask.cancel()
, theframe.f_back
chain becomesmysteriously truncated at arbitrary places in the call stack.
Your environment
The following example
pytest
code demonstrates the problem. A recursive stack of coroutines is resumed, either normally (after a sleep) or by sending aCancelledError
in. In the latter case, a traceback is generated and it is, in all cases, curiously truncated after just a few steps. Manually walking the stack will result in af.f_back == None
after a few steps.I employ a few different recursions, including a manual await-like method operating directly on the coroutine protocol. Initially I suspected that
coro.throw()
was deliberatly engineeded to mess with thef.f_back
of the frame chain, but even call stacks using regular coroutine recursion (theawait
keyword on async functions) appear truncated.traceback.print_stack()
is ultimately doing af = sys._getframe()
and following thef = f.f_back
chain. It can just as easily be verified that this chain is broken with aNone
after a short bit.The text was updated successfully, but these errors were encountered: