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.
# 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']
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
'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())
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
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
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())
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);
result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
#endif
bad:
- Py_XDECREF(py_modname);
return result;
}
""")
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 = []
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.
# 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