diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-06-26 22:24:51 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-06-26 22:24:51 (GMT) |
commit | e77f2e27987f99683b809981cb1230bfc566e7b7 (patch) | |
tree | 230797934676a25a1a61760a09a0b321348b586b | |
parent | 0ba70cc3c893f70cc9deb09447277539d7625403 (diff) | |
download | cpython-e77f2e27987f99683b809981cb1230bfc566e7b7.zip cpython-e77f2e27987f99683b809981cb1230bfc566e7b7.tar.gz cpython-e77f2e27987f99683b809981cb1230bfc566e7b7.tar.bz2 |
gen_getattr: make the gi_running and gi_frame members discoverable (but
not writable -- too dangerous!) from Python code.
-rw-r--r-- | Lib/test/test_generators.py | 24 | ||||
-rw-r--r-- | 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) <type 'generator'> >>> 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) +<type '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 = { |