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):
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;
}
""")
......
......@@ -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
......
"""
>>> 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