#2863: add gen.__name__ and add this name to generator repr().

This commit is contained in:
Georg Brandl 2008-05-15 15:08:32 +00:00
parent b346513044
commit c91210c06b
4 changed files with 49 additions and 3 deletions

View File

@ -917,6 +917,17 @@ StopIteration
>>> g.gi_code is f.func_code >>> g.gi_code is f.func_code
True True
Test the __name__ attribute and the repr()
>>> def f():
... yield 5
...
>>> g = f()
>>> g.__name__
'f'
>>> repr(g) # doctest: +ELLIPSIS
'<f generator object at ...>'
""" """
# conjoin is a simple backtracking generator, named in honor of Icon's # conjoin is a simple backtracking generator, named in honor of Icon's

View File

@ -92,7 +92,7 @@ Verify that parenthesis are required when used as a keyword argument value
Verify that parenthesis are required when used as a keyword argument value Verify that parenthesis are required when used as a keyword argument value
>>> dict(a = (i for i in xrange(10))) #doctest: +ELLIPSIS >>> dict(a = (i for i in xrange(10))) #doctest: +ELLIPSIS
{'a': <generator object at ...>} {'a': <<genexp> generator object at ...>}
Verify early binding for the outermost for-expression Verify early binding for the outermost for-expression

View File

@ -12,6 +12,11 @@ What's New in Python 2.6 beta 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #2863: generators now have a ``gen.__name__`` attribute that equals
``gen.gi_code.co_name``, like ``func.__name___`` that equals
``func.func_code.co_name``. The repr() of a generator now also contains
this name.
- Issue #2831: enumerate() now has a ``start`` argument. - Issue #2831: enumerate() now has a ``start`` argument.
- Issue #2801: fix bug in the float.is_integer method where a ValueError - Issue #2801: fix bug in the float.is_integer method where a ValueError

View File

@ -281,6 +281,36 @@ gen_iternext(PyGenObject *gen)
} }
static PyObject *
gen_repr(PyGenObject *gen)
{
char *code_name;
code_name = PyString_AsString(((PyCodeObject *)gen->gi_code)->co_name);
if (code_name == NULL)
return NULL;
return PyString_FromFormat("<%.200s generator object at %p>",
code_name, gen);
}
static PyObject *
gen_get_name(PyGenObject *gen)
{
PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name;
Py_INCREF(name);
return name;
}
PyDoc_STRVAR(gen__name__doc__,
"Return the name of the generator's associated code object.");
static PyGetSetDef gen_getsetlist[] = {
{"__name__", (getter)gen_get_name, NULL, NULL, gen__name__doc__},
{NULL}
};
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},
@ -306,7 +336,7 @@ PyTypeObject PyGen_Type = {
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_compare */ 0, /* tp_compare */
0, /* tp_repr */ (reprfunc)gen_repr, /* tp_repr */
0, /* tp_as_number */ 0, /* tp_as_number */
0, /* tp_as_sequence */ 0, /* tp_as_sequence */
0, /* tp_as_mapping */ 0, /* tp_as_mapping */
@ -326,7 +356,7 @@ PyTypeObject PyGen_Type = {
(iternextfunc)gen_iternext, /* tp_iternext */ (iternextfunc)gen_iternext, /* tp_iternext */
gen_methods, /* tp_methods */ gen_methods, /* tp_methods */
gen_memberlist, /* tp_members */ gen_memberlist, /* tp_members */
0, /* tp_getset */ gen_getsetlist, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */
0, /* tp_dict */ 0, /* tp_dict */