Commit b2c5022c authored by Tim Peters's avatar Tim Peters

gen_getattr: make the gi_running and gi_frame members discoverable (but

not writable -- too dangerous!) from Python code.
parent ae858111
......@@ -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").
......
......@@ -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 = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment