Commit 31a4969f authored by Stefan Behnel's avatar Stefan Behnel

add "__module__" attribute to coroutines and generators

parent 93c2d084
......@@ -3969,12 +3969,13 @@ class GeneratorDefNode(DefNode):
body_cname = self.gbody.entry.func_cname
name = code.intern_identifier(self.name)
qualname = code.intern_identifier(self.qualname)
module_name = code.intern_identifier(self.module_name)
code.putln('{')
code.putln('__pyx_CoroutineObject *gen = __Pyx_%s_New('
'(__pyx_coroutine_body_t) %s, (PyObject *) %s, %s, %s); %s' % (
'(__pyx_coroutine_body_t) %s, (PyObject *) %s, %s, %s, %s); %s' % (
'Coroutine' if self.is_coroutine else 'Generator',
body_cname, Naming.cur_scope_cname, name, qualname,
body_cname, Naming.cur_scope_cname, name, qualname, module_name,
code.error_goto_if_null('gen', self.pos)))
code.put_decref(Naming.cur_scope_cname, py_object_type)
if self.requires_classobj:
......
......@@ -341,13 +341,15 @@ typedef struct {
PyObject *yieldfrom;
PyObject *gi_name;
PyObject *gi_qualname;
PyObject *gi_modulename;
int resume_label;
// using T_BOOL for property below requires char value
char is_running;
} __pyx_CoroutineObject;
static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject *type, __pyx_coroutine_body_t body,
PyObject *closure, PyObject *name, PyObject *qualname); /*proto*/
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *closure,
PyObject *name, PyObject *qualname, PyObject *module_name); /*proto*/
static int __Pyx_Coroutine_clear(PyObject *self); /*proto*/
#if 1 || PY_VERSION_HEX < 0x030300B0
......@@ -364,8 +366,8 @@ static PyTypeObject *__pyx_CoroutineType = 0;
static PyTypeObject *__pyx_CoroutineAwaitType = 0;
#define __Pyx_Coroutine_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineType)
#define __Pyx_Coroutine_New(body, closure, name, qualname) \
__Pyx__Coroutine_New(__pyx_CoroutineType, body, closure, name, qualname)
#define __Pyx_Coroutine_New(body, closure, name, qualname, module_name) \
__Pyx__Coroutine_New(__pyx_CoroutineType, body, closure, name, qualname, module_name)
static int __pyx_Coroutine_init(void); /*proto*/
static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
......@@ -377,8 +379,8 @@ static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
static PyTypeObject *__pyx_GeneratorType = 0;
#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
#define __Pyx_Generator_New(body, closure, name, qualname) \
__Pyx__Coroutine_New(__pyx_GeneratorType, body, closure, name, qualname)
#define __Pyx_Generator_New(body, closure, name, qualname, module_name) \
__Pyx__Coroutine_New(__pyx_GeneratorType, body, closure, name, qualname, module_name)
static PyObject *__Pyx_Generator_Next(PyObject *self);
static int __pyx_Generator_init(void); /*proto*/
......@@ -998,8 +1000,9 @@ __Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value)
return 0;
}
static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject* type, __pyx_coroutine_body_t body,
PyObject *closure, PyObject *name, PyObject *qualname) {
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *closure,
PyObject *name, PyObject *qualname, PyObject *module_name) {
__pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type);
if (gen == NULL)
......@@ -1020,6 +1023,8 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject* type, __pyx_cor
gen->gi_qualname = qualname;
Py_XINCREF(name);
gen->gi_name = name;
Py_XINCREF(module_name);
gen->gi_modulename = module_name;
PyObject_GC_Track(gen);
return gen;
......@@ -1260,6 +1265,7 @@ static PyMemberDef __pyx_Coroutine_memberlist[] = {
{(char *) "cr_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
{(char*) "cr_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
(char*) PyDoc_STR("object being awaited, or None")},
{(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), PY_WRITE_RESTRICTED, 0},
{0, 0, 0, 0, 0}
};
......
......@@ -488,6 +488,15 @@ class CoroutineTest(unittest.TestCase):
def gen(): yield
self.assertFalse(hasattr(gen, '__await__'))
def test_func_attributes(self):
async def foo():
return 10
f = foo()
self.assertEqual(f.__name__, 'foo')
self.assertEqual(f.__qualname__, 'CoroutineTest.test_func_attributes.<locals>.foo')
self.assertEqual(f.__module__, 'test_coroutines_pep492')
def test_func_1(self):
async def foo():
return 10
......
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