X-Git-Url: http://git.tremily.us/?a=blobdiff_plain;f=Cython%2FCompiler%2FModuleNode.py;h=143ccbfbbc02c6e913fbf5ad5187881a84893e17;hb=ffcca353c096aa624a9655aee05219aca288eebb;hp=56fb98b7fbc7b93d7cf0e0bc5cc801326eca5105;hpb=4bb2ef8ea23e160cbd79c8e70c9e5467c462aecc;p=cython.git diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 56fb98b7..143ccbfb 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -270,11 +270,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code = globalstate['all_the_rest'] self.generate_cached_builtins_decls(env, code) + # generate lambda function definitions + for node in env.lambda_defs: + node.generate_function_definitions(env, code) + # generate normal function definitions self.body.generate_function_definitions(env, code) code.mark_pos(None) self.generate_typeobj_definitions(env, code) self.generate_method_table(env, code) - self.generate_filename_init_prototype(code) if env.has_import_star: self.generate_import_star(env, code) self.generate_pymoduledef_struct(env, code) @@ -408,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) @@ -522,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 @@ -562,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 @@ -613,7 +634,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln('static int %s = 0;' % Naming.clineno_cname) code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) code.putln('static const char *%s;' % Naming.filename_cname) - code.putln('static const char **%s;' % Naming.filetable_cname) # XXX this is a mess for utility_code in PyrexTypes.c_int_from_py_function.specialize_list: @@ -632,21 +652,20 @@ 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("") - code.putln("static const char *%s[] = {" % Naming.filenames_cname) + code.putln("static const char *%s[] = {" % Naming.filetable_cname) if code.globalstate.filename_list: for source_desc in code.globalstate.filename_list: filename = os.path.basename(source_desc.get_filenametable_entry()) escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"') - code.putln('"%s",' % - escaped_filename) + code.putln('"%s",' % escaped_filename) else: # Some C compilers don't like an empty array code.putln("0") @@ -985,7 +1004,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): type.vtabslot_cname, struct_type_cast, type.vtabptr_cname)) for entry in py_attrs: - if entry.name == "__weakref__": + if scope.is_internal or entry.name == "__weakref__": + # internal classes do not need None inits code.putln("p->%s = 0;" % entry.cname) else: code.put_init_var_to_py_none(entry, "p->%s", nanny=False) @@ -1535,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, ",") @@ -1566,10 +1586,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln( "};") - def generate_filename_init_prototype(self, code): - code.putln(""); - code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname) - def generate_import_star(self, env, code): env.use_utility_code(streq_utility_code) code.putln() @@ -1660,10 +1676,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("__pyx_refnanny = __Pyx_RefNanny->SetupContext(\"%s\", __LINE__, __FILE__);"% header3) code.putln("#endif") - self.generate_filename_init_call(code) - 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") code.putln("/*--- Library function declarations ---*/") env.generate_library_function_declarations(code) @@ -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) @@ -1797,9 +1816,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name, module_is_main=module_is_main)) - def generate_filename_init_call(self, code): - code.putln("%s();" % Naming.fileinit_cname) - def generate_pymoduledef_struct(self, env, code): if env.doc: doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc) @@ -2227,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; @@ -2261,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) @@ -2275,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; @@ -2287,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)) @@ -2315,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 @@ -2434,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; @@ -2444,19 +2461,26 @@ static int %(IMPORT_STAR)s(PyObject* m) { for(i=0; i= 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,