From: Haoyu Bai Date: Sun, 10 Oct 2010 10:06:04 +0000 (+0800) Subject: Fix T422 by making module name as a StringConst X-Git-Tag: 0.14.alpha0~285 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=0f9ba0d22a4337823b3d1576d579651c2e91e7f3;p=cython.git Fix T422 by making module name as a StringConst --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 2eabed1b..62de863c 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -4417,8 +4417,15 @@ class DictItemNode(ExprNode): def __iter__(self): return iter([self.key, self.value]) +class ModuleNameMixin(object): + def set_mod_name(self, env): + self.module_name = env.global_scope().qualified_name + + def get_py_mod_name(self, code): + return code.get_py_string_const( + self.module_name, identifier=True) -class ClassNode(ExprNode): +class ClassNode(ExprNode, ModuleNameMixin): # Helper class used in the implementation of Python # class definitions. Constructs a class object given # a name, tuple of bases and class dictionary. @@ -4427,7 +4434,7 @@ class ClassNode(ExprNode): # bases ExprNode Base class tuple # dict ExprNode Class dict (not owned by this node) # doc ExprNode or None Doc string - # module_name string Name of defining module + # module_name EncodedString Name of defining module subexprs = ['bases', 'doc'] @@ -4436,10 +4443,11 @@ class ClassNode(ExprNode): if self.doc: self.doc.analyse_types(env) self.doc = self.doc.coerce_to_pyobject(env) - self.module_name = env.global_scope().qualified_name self.type = py_object_type self.is_temp = 1 env.use_utility_code(create_class_utility_code); + #TODO(craig,haoyu) This should be moved to a better place + self.set_mod_name(env) def may_be_none(self): return False @@ -4453,13 +4461,14 @@ class ClassNode(ExprNode): 'PyDict_SetItemString(%s, "__doc__", %s)' % ( self.dict.py_result(), self.doc.py_result())) + py_mod_name = self.get_py_mod_name(code) code.putln( - '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % ( + '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % ( self.result(), self.bases.py_result(), self.dict.py_result(), cname, - self.module_name, + py_mod_name, code.error_goto_if_null(self.result(), self.pos))) code.put_gotref(self.py_result()) @@ -4521,14 +4530,15 @@ class UnboundMethodNode(ExprNode): code.put_gotref(self.py_result()) -class PyCFunctionNode(ExprNode): +class PyCFunctionNode(ExprNode, ModuleNameMixin): # Helper class used in the implementation of Python # class definitions. Constructs a PyCFunction object # from a PyMethodDef struct. # - # pymethdef_cname string PyMethodDef structure + # pymethdef_cname string PyMethodDef structure # self_object ExprNode or None # binding bool + # module_name EncodedString Name of defining module subexprs = [] self_object = None @@ -4541,6 +4551,9 @@ class PyCFunctionNode(ExprNode): if self.binding: env.use_utility_code(binding_cfunc_utility_code) + #TODO(craig,haoyu) This should be moved to a better place + self.set_mod_name(env) + def may_be_none(self): return False @@ -4555,15 +4568,17 @@ class PyCFunctionNode(ExprNode): def generate_result_code(self, code): if self.binding: - constructor = "%s_New" % Naming.binding_cfunc + constructor = "%s_NewEx" % Naming.binding_cfunc else: - constructor = "PyCFunction_New" + constructor = "PyCFunction_NewEx" + py_mod_name = self.get_py_mod_name(code) code.putln( - "%s = %s(&%s, %s); %s" % ( + '%s = %s(&%s, %s, %s); %s' % ( self.result(), constructor, self.pymethdef_cname, self.self_result_code(), + py_mod_name, code.error_goto_if_null(self.result(), self.pos))) code.put_gotref(self.py_result()) @@ -7093,23 +7108,15 @@ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { create_class_utility_code = UtilityCode( proto = """ -static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/ +static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, PyObject *modname); /*proto*/ """, impl = """ static PyObject *__Pyx_CreateClass( - PyObject *bases, PyObject *dict, PyObject *name, const char *modname) + PyObject *bases, PyObject *dict, PyObject *name, PyObject *modname) { - PyObject *py_modname; PyObject *result = 0; - #if PY_MAJOR_VERSION < 3 - py_modname = PyString_FromString(modname); - #else - py_modname = PyUnicode_FromString(modname); - #endif - if (!py_modname) - goto bad; - if (PyDict_SetItemString(dict, "__module__", py_modname) < 0) + if (PyDict_SetItemString(dict, "__module__", modname) < 0) goto bad; #if PY_MAJOR_VERSION < 3 result = PyClass_New(bases, dict, name); @@ -7117,7 +7124,6 @@ static PyObject *__Pyx_CreateClass( result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL); #endif bad: - Py_XDECREF(py_modname); return result; } """) diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 0c0fccad..9e0068a4 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -246,7 +246,7 @@ class Scope(object): self.qualified_name = qual_scope.qualify_name(name) self.scope_prefix = qual_scope.scope_prefix + mangled_name else: - self.qualified_name = name + self.qualified_name = EncodedString(name) self.scope_prefix = mangled_name self.entries = {} self.const_entries = [] @@ -348,7 +348,7 @@ class Scope(object): return entry def qualify_name(self, name): - return "%s.%s" % (self.qualified_name, name) + return EncodedString("%s.%s" % (self.qualified_name, name)) def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'): # Add an entry for a named constant. @@ -813,6 +813,7 @@ class ModuleScope(Scope): # Treat Spam/__init__.pyx specially, so that when Python loads # Spam/__init__.so, initSpam() is defined. self.module_name = parent_module.module_name + self.module_name = EncodedString(self.module_name) self.context = context self.module_cname = Naming.module_cname self.module_dict_cname = Naming.moddict_cname diff --git a/tests/run/method_module_name_T422.pyx b/tests/run/method_module_name_T422.pyx new file mode 100644 index 00000000..f7334c26 --- /dev/null +++ b/tests/run/method_module_name_T422.pyx @@ -0,0 +1,26 @@ +""" +>>> Foo.incr.__module__ is not None +True +>>> Foo.incr.__module__ == Foo.__module__ == bar.__module__ +True +>>> Simpleton.incr.__module__ == Simpleton.__module__ == bar.__module__ +True + +""" +class Foo(object): + def incr(self,x): + return x+1 + +def bar(): + pass + + +class Simpleton: + def __str__(self): + return "A simpleton" + + def incr(self,x): + """Increment x by one. + """ + return x+1 +