mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
#1473257: add generator.gi_code attribute that refers to
the original code object backing the generator. Patch by Collin Winter.
This commit is contained in:
parent
29604a1b4c
commit
0cdf9a36ec
4 changed files with 32 additions and 2 deletions
|
@ -18,6 +18,9 @@ typedef struct {
|
||||||
|
|
||||||
/* True if generator is being executed. */
|
/* True if generator is being executed. */
|
||||||
int gi_running;
|
int gi_running;
|
||||||
|
|
||||||
|
/* The code object backing the generator */
|
||||||
|
PyObject *gi_code;
|
||||||
|
|
||||||
/* List of weak reference. */
|
/* List of weak reference. */
|
||||||
PyObject *gi_weakreflist;
|
PyObject *gi_weakreflist;
|
||||||
|
|
|
@ -382,7 +382,7 @@ From the Iterators list, about the types of these things.
|
||||||
>>> type(i)
|
>>> type(i)
|
||||||
<type 'generator'>
|
<type 'generator'>
|
||||||
>>> [s for s in dir(i) if not s.startswith('_')]
|
>>> [s for s in dir(i) if not s.startswith('_')]
|
||||||
['close', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
|
['close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
|
||||||
>>> print i.next.__doc__
|
>>> print i.next.__doc__
|
||||||
x.next() -> the next value, or raise StopIteration
|
x.next() -> the next value, or raise StopIteration
|
||||||
>>> iter(i) is i
|
>>> iter(i) is i
|
||||||
|
@ -899,6 +899,24 @@ This one caused a crash (see SF bug 567538):
|
||||||
>>> print g.next()
|
>>> print g.next()
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
StopIteration
|
StopIteration
|
||||||
|
|
||||||
|
|
||||||
|
Test the gi_code attribute
|
||||||
|
|
||||||
|
>>> def f():
|
||||||
|
... yield 5
|
||||||
|
...
|
||||||
|
>>> g = f()
|
||||||
|
>>> g.gi_code is f.func_code
|
||||||
|
True
|
||||||
|
>>> g.next()
|
||||||
|
5
|
||||||
|
>>> g.next()
|
||||||
|
Traceback (most recent call last):
|
||||||
|
StopIteration
|
||||||
|
>>> g.gi_code is f.func_code
|
||||||
|
True
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# conjoin is a simple backtracking generator, named in honor of Icon's
|
# conjoin is a simple backtracking generator, named in honor of Icon's
|
||||||
|
|
|
@ -12,7 +12,11 @@ What's New in Python 2.6 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
- Backport of PyUnicode_FromString(), _FromStringAndSize(), _Format and
|
- Patch #1473257: generator objects gain a gi_code attribute. This is the
|
||||||
|
same object as the func_code attribute of the function that produced the
|
||||||
|
generator.
|
||||||
|
|
||||||
|
Backport of PyUnicode_FromString(), _FromStringAndSize(), _Format and
|
||||||
_FormatV from Python 3.0. Made PyLong_AsSsize_t and PyLong_FromSsize_t
|
_FormatV from Python 3.0. Made PyLong_AsSsize_t and PyLong_FromSsize_t
|
||||||
public functions.
|
public functions.
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ static int
|
||||||
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
|
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT((PyObject *)gen->gi_frame);
|
Py_VISIT((PyObject *)gen->gi_frame);
|
||||||
|
Py_VISIT(gen->gi_code);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ gen_dealloc(PyGenObject *gen)
|
||||||
|
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
Py_CLEAR(gen->gi_frame);
|
Py_CLEAR(gen->gi_frame);
|
||||||
|
Py_CLEAR(gen->gi_code);
|
||||||
PyObject_GC_Del(gen);
|
PyObject_GC_Del(gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,6 +284,7 @@ gen_iternext(PyGenObject *gen)
|
||||||
static PyMemberDef gen_memberlist[] = {
|
static PyMemberDef gen_memberlist[] = {
|
||||||
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO},
|
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO},
|
||||||
{"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO},
|
{"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO},
|
||||||
|
{"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), RO},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -352,6 +355,8 @@ PyGen_New(PyFrameObject *f)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gen->gi_frame = f;
|
gen->gi_frame = f;
|
||||||
|
Py_INCREF(f->f_code);
|
||||||
|
gen->gi_code = (PyObject *)(f->f_code);
|
||||||
gen->gi_running = 0;
|
gen->gi_running = 0;
|
||||||
gen->gi_weakreflist = NULL;
|
gen->gi_weakreflist = NULL;
|
||||||
_PyObject_GC_TRACK(gen);
|
_PyObject_GC_TRACK(gen);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue