From e77f2e27987f99683b809981cb1230bfc566e7b7 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Tue, 26 Jun 2001 22:24:51 +0000 Subject: gen_getattr: make the gi_running and gi_frame members discoverable (but not writable -- too dangerous!) from Python code. --- Lib/test/test_generators.py | 24 ++++++++++++++++++++++-- Python/ceval.c | 21 +++++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 3646001..86898bb 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -368,7 +368,7 @@ Next one was posted to c.l.py. [1, 2, 3, 4] 5-combs of [1, 2, 3, 4]: -# From the Iterators list, about the types of these things. +From the Iterators list, about the types of these things. >>> def g(): ... yield 1 @@ -379,7 +379,7 @@ Next one was posted to c.l.py. >>> type(i) >>> dir(i) -['next'] +['gi_frame', 'gi_running', 'next'] >>> print i.next.__doc__ next() -- get the next value, or raise StopIteration >>> iter(i) is i @@ -387,6 +387,26 @@ next() -- get the next value, or raise StopIteration >>> import types >>> isinstance(i, types.GeneratorType) 1 + +And more, added later. + +>>> i.gi_running +0 +>>> type(i.gi_frame) + +>>> i.gi_running = 42 +Traceback (most recent call last): + ... +TypeError: object has read-only attributes +>>> def g(): +... yield me.gi_running +>>> me = g() +>>> me.gi_running +0 +>>> me.next() +1 +>>> me.gi_running +0 """ # Fun tests (for sufficiently warped notions of "fun"). diff --git a/Python/ceval.c b/Python/ceval.c index e4620ab..a73e4d0 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -115,8 +115,8 @@ typedef struct { PyFrameObject *gi_frame; - /* True if generator is being executed. */ - int gi_running; + /* True if generator is being executed. */ + int gi_running; } genobject; static PyObject * @@ -207,14 +207,27 @@ gen_getiter(PyObject *gen) static struct PyMethodDef gen_methods[] = { {"next", (PyCFunction)gen_next, METH_VARARGS, - "next() -- get the next value, or raise StopIteration"}, + "next() -- get the next value, or raise StopIteration"}, {NULL, NULL} /* Sentinel */ }; static PyObject * gen_getattr(genobject *gen, char *name) { - return Py_FindMethod(gen_methods, (PyObject *)gen, name); + PyObject *result; + + if (strcmp(name, "gi_frame") == 0) { + result = (PyObject *)gen->gi_frame; + assert(result != NULL); + Py_INCREF(result); + } + else if (strcmp(name, "gi_running") == 0) + result = (PyObject *)PyInt_FromLong((long)gen->gi_running); + else if (strcmp(name, "__members__") == 0) + result = Py_BuildValue("[ss]", "gi_frame", "gi_running"); + else + result = Py_FindMethod(gen_methods, (PyObject *)gen, name); + return result; } statichere PyTypeObject gentype = { -- cgit v0.12