diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 98b7cb7..dd89446 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -178,6 +178,9 @@ attributes: +-----------+-----------------+---------------------------+ | | gi_code | code | +-----------+-----------------+---------------------------+ +| | gi_yieldfrom | generator currently | +| | | yielding from | ++-----------+-----------------+---------------------------+ | builtin | __doc__ | documentation string | +-----------+-----------------+---------------------------+ | | __name__ | original name of this | diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index fe4b138..03604aa 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -624,7 +624,7 @@ From the Iterators list, about the types of these things. >>> type(i) >>> [s for s in dir(i) if not s.startswith('_')] -['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw'] +['close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw'] >>> from test.support import HAVE_DOCSTRINGS >>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implement next(self).') Implement next(self). @@ -2105,6 +2105,23 @@ test_generators just happened to be the test that drew these out. """ +gi_yieldfrom_tests = """ +>>> def a(): +... yield +... +>>> def b(): +... yield from a() +... +>>> gen_b = b() +>>> gen_b.gi_yieldfrom == None +True +>>> gen_b.send(None) +>>> gen_b.gi_yieldfrom.gi_code.co_name == 'a' +True + +""" + + __test__ = {"tut": tutorial_tests, "pep": pep_tests, "email": email_tests, @@ -2114,6 +2131,7 @@ __test__ = {"tut": tutorial_tests, "weakref": weakref_tests, "coroutine": coroutine_tests, "refleaks": refleaks_tests, + "gi_yieldfrom": gi_yieldfrom_tests, } # Magic test name that regrtest.py invokes *after* importing this module. diff --git a/Objects/genobject.c b/Objects/genobject.c index 5d3b66c..7f954b6 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -569,11 +569,23 @@ 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, + PyDoc_STR("generator currently yielding from")}, {NULL} /* Sentinel */ };