]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gen_getattr: make the gi_running and gi_frame members discoverable (but
authorTim Peters <tim.peters@gmail.com>
Tue, 26 Jun 2001 22:24:51 +0000 (22:24 +0000)
committerTim Peters <tim.peters@gmail.com>
Tue, 26 Jun 2001 22:24:51 +0000 (22:24 +0000)
not writable -- too dangerous!) from Python code.

Lib/test/test_generators.py
Python/ceval.c

index 3646001abab2776a5447acf4766f5f5d924c506f..86898bb9f11582f3463a3be263408fd24436445d 100644 (file)
@@ -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").
index e4620ab6c4e3b5a289dc3bd0742cc4586b23a475..a73e4d06a72446bd265c66ffaeb8d1a9872f145f 100644 (file)
@@ -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 = {