<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Jun 13, 2015 at 12:22 AM, Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On 13 June 2015 at 04:13, Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
> IOW I don't think that the problem here is that you haven't sufficiently<br>
> motivated your use case -- you are asking for information that just isn't<br>
> available. (Which is actually where you started the thread -- you can get to<br>
> the frame of the coroutine but there's nowhere to go from that frame.)<br>
<br>
</span>If I'm understanding Ben's request correctly, it isn't really the<br>
stack trace that he's interested in (as you say, that specific<br>
phrasing doesn't match the way coroutine suspension works), but rather<br>
having visibility into the chain of control flow delegation for<br>
currently suspended frames: what operation is the outermost frame<br>
ultimately blocked *on*, and how did it get to the point of waiting<br>
for that operation?<br>
<br>
At the moment, all of the coroutine and generator-iterator resumption<br>
information is implicit in the frame state, so we can't externally<br>
introspect the delegation of control flow in a case like Ben's<br>
original example (for coroutines) or like this one for generators:<br>
<br>
    def g1():<br>
        yield 42<br>
<br>
    def g2():<br>
        yield from g1()<br>
<br>
    g = g2()<br>
    next(g)<br>
    # We can tell here that g is suspended<br>
    # We can't tell that it delegated flow to a g1() instance<br>
<br>
I wonder if in 3.6 it might be possible to *add* some bookkeeping to<br>
"await" and "yield from" expressions that provides external visibility<br>
into the underlying iterable or coroutine that the generator-iterator<br>
or coroutine has delegated flow control to. As an initial assessment,<br>
the runtime cost would be:<br>
<br>
* an additional pointer added to generator/coroutine objects to track<br>
control flow delegation<br>
* setting that when suspending in "await" and "yield from" expressions<br>
* clearing it when resuming in "await" and "yield from" expressions<br>
<br>
(This would be a read-only borrowed reference from a Python level<br>
perspective, so it shouldn't be necessary to alter the reference count<br>
- we'd just be aliasing the existing reference from the frame's<br>
internal stack state)<br clear="all"></blockquote><div><br>Ah, this makes sense. I think the object you're after is 'reciever' [sic] in the YIELD_FROM opcode implementation, right?<br></div></div><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div></div>