New submission from Nathaniel Smith:

The attached script sets up a stack of generators calling each other via 'yield 
from': f yields from g yield from h. Then the generator at the bottom of the 
stack yields.

Before they yield, sys._getframe shows the expected stack (or if you put in 
traceback.print_stack() you get the same thing).

After they yield, it depends: if the generator is resumed via 'gen.send(None)', 
then the stack looks sensible. But if the generator is resumed via 
'gen.throw(...)', then the stack is weird: Objects/genobject.c:_gen_throw 
implements 'yield from' in an weird manual way, where it first directly resumes 
the innermost generator frame, and then propagates any result to the next 
generator frame, etc. So the output I get from the sample script is:

~$ python3.6 weird-throw-stack.py
-- f before yielding --
f
<module>
-- g before yielding --
g
f
<module>
-- h before yielding --
h
g
f
<module>
-- h after yielding --
h
<module>
-- g after yielding --
g
<module>
-- f after yielding --
f
<module>

This causes problems for stack-based profiling 
(https://github.com/vmprof/vmprof-python/issues/117), debuggers, and other 
tools that need to introspect the stack.

----------
files: weird-throw-stack.py
messages: 288010
nosy: njs
priority: normal
severity: normal
status: open
title: Incorrect stack traces when re-entering a generator/coroutine stack via 
.throw()
versions: Python 3.5, Python 3.6, Python 3.7
Added file: http://bugs.python.org/file46644/weird-throw-stack.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue29590>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to