[Python-Dev] Obtaining stack-frames from co-routine objects
Ben Leslie
benno at benno.id.au
Sun Jun 14 02:00:05 CEST 2015
On 14 June 2015 at 09:20, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Nick Coghlan wrote:
>>
>> I wonder if in 3.6 it might be possible to *add* some bookkeeping to
>> "await" and "yield from" expressions that provides external visibility
>> into the underlying iterable or coroutine that the generator-iterator
>> or coroutine has delegated flow control to.
>
>
> In my original implementation of yield-from, stack frames
> had an f_yieldfrom slot referring to the object being
> yielded from.
>
> I gather that slot no longer exists at the C level, but
> it ought to be possible to provide a Python attribute or
> method returning the same information.
OK, this is really easy to implement actually. I implemented it as gi_yieldfrom
on the generator object rather than f_yieldfrom on the frame object,
primarily as most of the related code is already in the genobject.c module.
Something like this:
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 3c32e7b..bc42fe5 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -553,11 +553,22 @@ gen_set_qualname(PyGenObject *op, PyObject *value)
return 0;
}
+static PyObject *
+gen_getyieldfrom(PyGenObject *gen)
+{
+ PyObject *yf = gen_yf(gen);
+ if (yf == NULL)
+ Py_RETURN_NONE;
+
+ return yf;
+}
+
static PyGetSetDef gen_getsetlist[] = {
{"__name__", (getter)gen_get_name, (setter)gen_set_name,
PyDoc_STR("name of the generator")},
{"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
PyDoc_STR("qualified name of the generator")},
+ {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL, NULL},
{NULL} /* Sentinel */
};
(Note: Above probably doesn't exactly follow correct coding conventions, and
probably need to add an appropriate doc string.)
This greatly simplifies my very original 'show' routine to:
def show(coro):
print("{}:{} ({})".format(coro.gi_frame.f_code.co_filename,
coro.gi_frame.f_lineno, coro))
if coro.gi_yieldfrom:
show(coro.gi_yieldfrom)
I think this would give the widest flexibility for non-CPython
implementations to implement
the same property in the most appropriate manner.
If this seems like a good approach I'll try and work it in to a
suitable patch for contribution.
Cheers,
Ben
More information about the Python-Dev
mailing list