Commit 0f9ba0d2 authored by Haoyu Bai's avatar Haoyu Bai

Fix T422 by making module name as a StringConst

parent e74ad055
...@@ -4417,8 +4417,15 @@ class DictItemNode(ExprNode): ...@@ -4417,8 +4417,15 @@ class DictItemNode(ExprNode):
def __iter__(self): def __iter__(self):
return iter([self.key, self.value]) 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 # Helper class used in the implementation of Python
# class definitions. Constructs a class object given # class definitions. Constructs a class object given
# a name, tuple of bases and class dictionary. # a name, tuple of bases and class dictionary.
...@@ -4427,7 +4434,7 @@ class ClassNode(ExprNode): ...@@ -4427,7 +4434,7 @@ class ClassNode(ExprNode):
# bases ExprNode Base class tuple # bases ExprNode Base class tuple
# dict ExprNode Class dict (not owned by this node) # dict ExprNode Class dict (not owned by this node)
# doc ExprNode or None Doc string # doc ExprNode or None Doc string
# module_name string Name of defining module # module_name EncodedString Name of defining module
subexprs = ['bases', 'doc'] subexprs = ['bases', 'doc']
...@@ -4436,10 +4443,11 @@ class ClassNode(ExprNode): ...@@ -4436,10 +4443,11 @@ class ClassNode(ExprNode):
if self.doc: if self.doc:
self.doc.analyse_types(env) self.doc.analyse_types(env)
self.doc = self.doc.coerce_to_pyobject(env) self.doc = self.doc.coerce_to_pyobject(env)
self.module_name = env.global_scope().qualified_name
self.type = py_object_type self.type = py_object_type
self.is_temp = 1 self.is_temp = 1
env.use_utility_code(create_class_utility_code); 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): def may_be_none(self):
return False return False
...@@ -4453,13 +4461,14 @@ class ClassNode(ExprNode): ...@@ -4453,13 +4461,14 @@ class ClassNode(ExprNode):
'PyDict_SetItemString(%s, "__doc__", %s)' % ( 'PyDict_SetItemString(%s, "__doc__", %s)' % (
self.dict.py_result(), self.dict.py_result(),
self.doc.py_result())) self.doc.py_result()))
py_mod_name = self.get_py_mod_name(code)
code.putln( code.putln(
'%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % ( '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
self.result(), self.result(),
self.bases.py_result(), self.bases.py_result(),
self.dict.py_result(), self.dict.py_result(),
cname, cname,
self.module_name, py_mod_name,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
...@@ -4521,7 +4530,7 @@ class UnboundMethodNode(ExprNode): ...@@ -4521,7 +4530,7 @@ class UnboundMethodNode(ExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class PyCFunctionNode(ExprNode): class PyCFunctionNode(ExprNode, ModuleNameMixin):
# Helper class used in the implementation of Python # Helper class used in the implementation of Python
# class definitions. Constructs a PyCFunction object # class definitions. Constructs a PyCFunction object
# from a PyMethodDef struct. # from a PyMethodDef struct.
...@@ -4529,6 +4538,7 @@ class PyCFunctionNode(ExprNode): ...@@ -4529,6 +4538,7 @@ class PyCFunctionNode(ExprNode):
# pymethdef_cname string PyMethodDef structure # pymethdef_cname string PyMethodDef structure
# self_object ExprNode or None # self_object ExprNode or None
# binding bool # binding bool
# module_name EncodedString Name of defining module
subexprs = [] subexprs = []
self_object = None self_object = None
...@@ -4541,6 +4551,9 @@ class PyCFunctionNode(ExprNode): ...@@ -4541,6 +4551,9 @@ class PyCFunctionNode(ExprNode):
if self.binding: if self.binding:
env.use_utility_code(binding_cfunc_utility_code) 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): def may_be_none(self):
return False return False
...@@ -4555,15 +4568,17 @@ class PyCFunctionNode(ExprNode): ...@@ -4555,15 +4568,17 @@ class PyCFunctionNode(ExprNode):
def generate_result_code(self, code): def generate_result_code(self, code):
if self.binding: if self.binding:
constructor = "%s_New" % Naming.binding_cfunc constructor = "%s_NewEx" % Naming.binding_cfunc
else: else:
constructor = "PyCFunction_New" constructor = "PyCFunction_NewEx"
py_mod_name = self.get_py_mod_name(code)
code.putln( code.putln(
"%s = %s(&%s, %s); %s" % ( '%s = %s(&%s, %s, %s); %s' % (
self.result(), self.result(),
constructor, constructor,
self.pymethdef_cname, self.pymethdef_cname,
self.self_result_code(), self.self_result_code(),
py_mod_name,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
...@@ -7093,23 +7108,15 @@ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { ...@@ -7093,23 +7108,15 @@ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
create_class_utility_code = UtilityCode( create_class_utility_code = UtilityCode(
proto = """ 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 = """ impl = """
static PyObject *__Pyx_CreateClass( 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; PyObject *result = 0;
#if PY_MAJOR_VERSION < 3 if (PyDict_SetItemString(dict, "__module__", modname) < 0)
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)
goto bad; goto bad;
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
result = PyClass_New(bases, dict, name); result = PyClass_New(bases, dict, name);
...@@ -7117,7 +7124,6 @@ static PyObject *__Pyx_CreateClass( ...@@ -7117,7 +7124,6 @@ static PyObject *__Pyx_CreateClass(
result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL); result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
#endif #endif
bad: bad:
Py_XDECREF(py_modname);
return result; return result;
} }
""") """)
......
...@@ -246,7 +246,7 @@ class Scope(object): ...@@ -246,7 +246,7 @@ class Scope(object):
self.qualified_name = qual_scope.qualify_name(name) self.qualified_name = qual_scope.qualify_name(name)
self.scope_prefix = qual_scope.scope_prefix + mangled_name self.scope_prefix = qual_scope.scope_prefix + mangled_name
else: else:
self.qualified_name = name self.qualified_name = EncodedString(name)
self.scope_prefix = mangled_name self.scope_prefix = mangled_name
self.entries = {} self.entries = {}
self.const_entries = [] self.const_entries = []
...@@ -348,7 +348,7 @@ class Scope(object): ...@@ -348,7 +348,7 @@ class Scope(object):
return entry return entry
def qualify_name(self, name): 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'): def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'):
# Add an entry for a named constant. # Add an entry for a named constant.
...@@ -813,6 +813,7 @@ class ModuleScope(Scope): ...@@ -813,6 +813,7 @@ class ModuleScope(Scope):
# Treat Spam/__init__.pyx specially, so that when Python loads # Treat Spam/__init__.pyx specially, so that when Python loads
# Spam/__init__.so, initSpam() is defined. # Spam/__init__.so, initSpam() is defined.
self.module_name = parent_module.module_name self.module_name = parent_module.module_name
self.module_name = EncodedString(self.module_name)
self.context = context self.context = context
self.module_cname = Naming.module_cname self.module_cname = Naming.module_cname
self.module_dict_cname = Naming.moddict_cname self.module_dict_cname = Naming.moddict_cname
......
"""
>>> 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
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