applied fix by haoyu for bug #543
[cython.git] / Cython / Compiler / ModuleNode.py
index 6b859990fe2688700536f7ec72871e38d908e16d..143ccbfbbc02c6e913fbf5ad5187881a84893e17 100644 (file)
@@ -411,7 +411,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         for module in modules:
             defined_here = module is env
             modulecode.putln("/* Module declarations from %s */" %
-                       module.qualified_name.encode("ASCII", "ignore"))
+                             module.qualified_name)
             self.generate_global_declarations(module, modulecode, defined_here)
             self.generate_cfunction_predeclarations(module, modulecode, defined_here)
 
@@ -525,11 +525,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
 
 #if PY_MAJOR_VERSION >= 3
   #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
   #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
   #define PyString_CheckExact          PyUnicode_CheckExact
-#else
+#endif
+
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
   #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
   #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
 #endif
 
 #if PY_MAJOR_VERSION >= 3
@@ -565,7 +583,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
 
         code.put("""
 #if PY_MAJOR_VERSION >= 3
-  #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
 #endif
 
 #if PY_VERSION_HEX < 0x02050000
@@ -634,11 +652,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
     def generate_includes(self, env, cimported_modules, code):
         includes = []
         for filename in env.include_files:
-            # fake decoding of filenames to their original byte sequence
-            if filename[0] == '<' and filename[-1] == '>':
-                code.putln('#include %s' % filename)
+            byte_decoded_filenname = str(filename)
+            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
+                code.putln('#include %s' % byte_decoded_filenname)
             else:
-                code.putln('#include "%s"' % filename)
+                code.putln('#include "%s"' % byte_decoded_filenname)
     
     def generate_filename_table(self, code):
         code.putln("")
@@ -1537,7 +1555,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
     def generate_method_table(self, env, code):
         code.putln("")
         code.putln(
-            "static struct PyMethodDef %s[] = {" % 
+            "static PyMethodDef %s[] = {" % 
                 env.method_table_cname)
         for entry in env.pyfunc_entries:
             code.put_pymethoddef(entry, ",")
@@ -1659,8 +1677,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("#endif")
 
         code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
-        code.putln("%s = __Pyx_PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
-        
+        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
+
         code.putln("#ifdef %s_USED" % Naming.binding_cfunc)
         code.putln("if (%s_init() < 0) %s" % (Naming.binding_cfunc, code.error_goto(self.pos)))
         code.putln("#endif")
@@ -1753,7 +1771,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         if not Options.generate_cleanup_code:
             return
         code.globalstate.use_utility_code(register_cleanup_utility_code)
-        code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
+        code.putln('static PyObject *%s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused) {' % 
+                   Naming.cleanup_cname)
         if Options.generate_cleanup_code >= 2:
             code.putln("/*--- Global cleanup code ---*/")
             rev_entries = list(env.var_entries)
@@ -2177,7 +2196,11 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
         PyOS_snprintf(warning, sizeof(warning), 
             "%s.%s size changed, may indicate binary incompatibility",
             module_name, class_name);
+        #if PY_VERSION_HEX < 0x02050000
+        PyErr_Warn(NULL, warning);
+        #else
         PyErr_WarnEx(NULL, warning, 0);
+        #endif
     }
     else if (((PyTypeObject *)result)->tp_basicsize != size) {
         PyErr_Format(PyExc_ValueError, 
@@ -2220,10 +2243,10 @@ static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *s
             goto bad;
     }
     tmp.fp = f;
-#if PY_VERSION_HEX < 0x03010000
-    cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
-#else
+#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
     cobj = PyCapsule_New(tmp.p, sig, 0);
+#else
+    cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
 #endif
     if (!cobj)
         goto bad;
@@ -2254,9 +2277,6 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
         void (*fp)(void);
         void *p;
     } tmp;
-#if PY_VERSION_HEX < 0x03010000
-    const char *desc, *s1, *s2;
-#endif
 
     d = PyObject_GetAttrString(module, (char *)"%(API)s");
     if (!d)
@@ -2268,7 +2288,16 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
                 PyModule_GetName(module), funcname);
         goto bad;
     }
-#if PY_VERSION_HEX < 0x03010000
+#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
+    if (!PyCapsule_IsValid(cobj, sig)) {
+        PyErr_Format(PyExc_TypeError,
+            "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
+             PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj));
+        goto bad;
+    }
+    tmp.p = PyCapsule_GetPointer(cobj, sig);
+#else
+    {const char *desc, *s1, *s2;
     desc = (const char *)PyCObject_GetDesc(cobj);
     if (!desc)
         goto bad;
@@ -2280,15 +2309,7 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
              PyModule_GetName(module), funcname, sig, desc);
         goto bad;
     }
-    tmp.p = PyCObject_AsVoidPtr(cobj);
-#else
-    if (!PyCapsule_IsValid(cobj, sig)) {
-        PyErr_Format(PyExc_TypeError,
-            "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
-             PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj));
-        goto bad;
-    }
-    tmp.p = PyCapsule_GetPointer(cobj, sig);
+    tmp.p = PyCObject_AsVoidPtr(cobj);}
 #endif
     *f = tmp.fp;
     if (!(*f))
@@ -2308,9 +2329,9 @@ bad:
 register_cleanup_utility_code = UtilityCode(
 proto = """
 static int __Pyx_RegisterCleanup(void); /*proto*/
-static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
-static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
-""",
+static PyObject* %(module_cleanup)s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&%(module_cleanup)s, METH_NOARGS, 0};
+""" % {'module_cleanup': Naming.cleanup_cname},
 impl = """
 static int __Pyx_RegisterCleanup(void) {
     /* Don't use Py_AtExit because that has a 32-call limit 
@@ -2427,6 +2448,9 @@ static int %(IMPORT_STAR)s(PyObject* m) {
     char* s;
     PyObject *locals = 0;
     PyObject *list = 0;
+#if PY_MAJOR_VERSION >= 3
+    PyObject *utf8_name = 0;
+#endif
     PyObject *name;
     PyObject *item;
     
@@ -2437,19 +2461,26 @@ static int %(IMPORT_STAR)s(PyObject* m) {
     for(i=0; i<PyList_GET_SIZE(list); i++) {
         name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
         item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
-#if PY_MAJOR_VERSION < 3
-        s = PyString_AsString(name);
+#if PY_MAJOR_VERSION >= 3
+        utf8_name = PyUnicode_AsUTF8String(name);
+        if (!utf8_name) goto bad;
+        s = PyBytes_AS_STRING(utf8_name);
+        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
+        Py_DECREF(utf8_name); utf8_name = 0;
 #else
-        s = PyUnicode_AsString(name);
-#endif
+        s = PyString_AsString(name);
         if (!s) goto bad;
         if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
+#endif
     }
     ret = 0;
     
 bad:
     Py_XDECREF(locals);
     Py_XDECREF(list);
+#if PY_MAJOR_VERSION >= 3
+    Py_XDECREF(utf8_name);
+#endif
     return ret;
 }
 """ % {'IMPORT_STAR'     : Naming.import_star,