From: Robert Bradshaw Date: Thu, 15 Aug 2013 06:44:40 +0000 (-0700) Subject: Correct globals for shared function types. X-Git-Tag: 0.20b1~361^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=baf76aacf5639eab4002c7ff22d8f14d34b148fc;p=platform%2Fupstream%2Fpython-cython.git Correct globals for shared function types. --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 7f1fdcb..4488888 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -7236,7 +7236,7 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin): flags = '0' code.putln( - '%s = %s(&%s, %s, %s, %s, %s, %s); %s' % ( + '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % ( self.result(), constructor, self.pymethdef_cname, @@ -7244,6 +7244,7 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin): self.get_py_qualified_name(code), self.self_result_code(), self.get_py_mod_name(code), + "PyModule_GetDict(%s)" % Naming.module_cname, code_object_result, code.error_goto_if_null(self.result(), self.pos))) diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c index 0b6d975..7378b91 100644 --- a/Cython/Utility/CythonFunction.c +++ b/Cython/Utility/CythonFunction.c @@ -27,6 +27,7 @@ typedef struct { PyObject *func_name; PyObject *func_qualname; PyObject *func_doc; + PyObject *func_globals; PyObject *func_code; PyObject *func_closure; PyObject *func_classobj; /* No-args super() class cell */ @@ -44,12 +45,13 @@ typedef struct { static PyTypeObject *__pyx_CyFunctionType = 0; -#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, code) \ - __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, code) +#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \ + __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code) static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *self, PyObject *module, + PyObject *self, + PyObject *module, PyObject *globals, PyObject* code); static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, @@ -213,18 +215,11 @@ __Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value) return 0; } -// TODO: we implicitly use the global module to get func_globals. This -// will need to be passed into __Pyx_CyFunction_NewEx() if we share -// this type across modules. We currently avoid doing this to reduce -// the overhead of creating a function object, and to avoid keeping a -// reference to the module dict as long as we don't need to. - static PyObject * -__Pyx_CyFunction_get_globals(CYTHON_UNUSED __pyx_CyFunctionObject *op) +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op) { - PyObject* dict = PyModule_GetDict(${module_cname}); - Py_XINCREF(dict); - return dict; + Py_INCREF(op->func_globals); + return op->func_globals; } static PyObject * @@ -400,7 +395,7 @@ static PyMethodDef __pyx_CyFunction_methods[] = { static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* code) { + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type); if (op == NULL) return NULL; @@ -418,6 +413,8 @@ static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int f op->func_qualname = qualname; op->func_doc = NULL; op->func_classobj = NULL; + op->func_globals = globals; + Py_INCREF(op->func_globals); Py_XINCREF(code); op->func_code = code; /* Dynamic Default args */ @@ -440,6 +437,7 @@ __Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) Py_CLEAR(m->func_name); Py_CLEAR(m->func_qualname); Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); Py_CLEAR(m->func_code); Py_CLEAR(m->func_classobj); Py_CLEAR(m->defaults_tuple); @@ -477,6 +475,7 @@ static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, Py_VISIT(m->func_name); Py_VISIT(m->func_qualname); Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); Py_VISIT(m->func_code); Py_VISIT(m->func_classobj); Py_VISIT(m->defaults_tuple); @@ -708,11 +707,12 @@ typedef struct { PyObject *self; } __pyx_FusedFunctionObject; -#define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, code) \ - __pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, code) +#define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, globals, code) \ + __pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, globals, code) static PyObject *__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, - PyObject *qualname, PyObject *self, PyObject *module, + PyObject *qualname, PyObject *self, + PyObject *module, PyObject *globals, PyObject *code); static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self); @@ -727,11 +727,12 @@ static int __pyx_FusedFunction_init(void); static PyObject * __pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject *qualname, PyObject *self, - PyObject *module, PyObject *code) + PyObject *module, PyObject *globals, + PyObject *code) { __pyx_FusedFunctionObject *fusedfunc = (__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname, - self, module, code); + self, module, globals, code); if (!fusedfunc) return NULL; @@ -789,6 +790,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type) ((__pyx_CyFunctionObject *) func)->func_qualname, ((__pyx_CyFunctionObject *) func)->func_closure, ((PyCFunctionObject *) func)->m_module, + ((__pyx_CyFunctionObject *) func)->func_globals, ((__pyx_CyFunctionObject *) func)->func_code); if (!meth) return NULL; diff --git a/tests/run/common_utility_types.srctree b/tests/run/common_utility_types.srctree index c5ea807..1f3d2ae 100644 --- a/tests/run/common_utility_types.srctree +++ b/tests/run/common_utility_types.srctree @@ -30,5 +30,9 @@ def funcB(): print("importing...") import a, b print(type(a.funcA)) + assert type(a.funcA).__name__ == 'cython_function_or_method' assert type(a.funcA) is type(b.funcB) + +assert a.funcA.func_globals is a.__dict__ +assert b.funcB.func_globals is b.__dict__