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