]> granicus.if.org Git - python/commitdiff
#1473257: add generator.gi_code attribute that refers to
authorGeorg Brandl <georg@python.org>
Sat, 26 Jan 2008 14:14:20 +0000 (14:14 +0000)
committerGeorg Brandl <georg@python.org>
Sat, 26 Jan 2008 14:14:20 +0000 (14:14 +0000)
the original code object backing the generator. Patch by Collin Winter.

Include/genobject.h
Lib/test/test_generators.py
Misc/NEWS
Objects/genobject.c

index 11c6823eaa2156ccce0f9a2bfef33e709e950166..135561b701b025804016c6bf0c181e013214ff1d 100644 (file)
@@ -18,6 +18,9 @@ typedef struct {
 
        /* True if generator is being executed. */
        int gi_running;
+    
+       /* The code object backing the generator */
+       PyObject *gi_code;
 
        /* List of weak reference. */
        PyObject *gi_weakreflist;
index ce3db72e66c489eaf9f08a8f7b0c2e49d76dccd8..ab0fca05064b42ac35b523251b22e809c86207a2 100644 (file)
@@ -382,7 +382,7 @@ From the Iterators list, about the types of these things.
 >>> type(i)
 <type 'generator'>
 >>> [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__
 x.next() -> the next value, or raise StopIteration
 >>> iter(i) is i
@@ -899,6 +899,24 @@ This one caused a crash (see SF bug 567538):
 >>> print g.next()
 Traceback (most recent call last):
 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
index 16034183e4ee094e5016ffbe672238a502ea5875..2d463571d4ba7002086e94b71d8e1460bd030247 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,7 +12,11 @@ What's New in Python 2.6 alpha 1?
 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
   public functions.
 
index 4ef710bfcd9a8bc7377ac7f4bbc0d8693855d291..38682955c3ade3c3726c8922f099a400e4f9e257 100644 (file)
@@ -11,6 +11,7 @@ static int
 gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
 {
        Py_VISIT((PyObject *)gen->gi_frame);
+       Py_VISIT(gen->gi_code);
        return 0;
 }
 
@@ -35,6 +36,7 @@ gen_dealloc(PyGenObject *gen)
 
        _PyObject_GC_UNTRACK(self);
        Py_CLEAR(gen->gi_frame);
+       Py_CLEAR(gen->gi_code);
        PyObject_GC_Del(gen);
 }
 
@@ -282,6 +284,7 @@ gen_iternext(PyGenObject *gen)
 static PyMemberDef gen_memberlist[] = {
        {"gi_frame",    T_OBJECT, offsetof(PyGenObject, gi_frame),      RO},
        {"gi_running",  T_INT,    offsetof(PyGenObject, gi_running),    RO},
+        {"gi_code",     T_OBJECT, offsetof(PyGenObject, gi_code),  RO},
        {NULL}  /* Sentinel */
 };
 
@@ -352,6 +355,8 @@ PyGen_New(PyFrameObject *f)
                return NULL;
        }
        gen->gi_frame = f;
+       Py_INCREF(f->f_code);
+       gen->gi_code = (PyObject *)(f->f_code);
        gen->gi_running = 0;
        gen->gi_weakreflist = NULL;
        _PyObject_GC_TRACK(gen);