From 4e772113e900c2a9d9ac5058cb96f77cad1daeb8 Mon Sep 17 00:00:00 2001 From: da-woods Date: Thu, 20 Apr 2023 18:08:45 +0100 Subject: Distinguish 'api' import functions from different Cython versions (GH-5383) (#5390) Fixes issue with changed signature for these functions between Cython releases Issue was reported here: https://github.com/cython/cython/pull/5289#issuecomment-1509371606 --- Cython/Compiler/ModuleNode.py | 29 ++++++++++++++---------- Cython/Compiler/Naming.py | 2 ++ Cython/Utility/ImportExport.c | 51 +++++++++++++++++++++++-------------------- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index e81b63d0a..b3201ce47 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -293,14 +293,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): cname = env.mangle(Naming.func_prefix_api, entry.name) sig = entry.type.signature_string() h_code.putln( - 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' - % (entry.name, cname, sig)) + 'if (__Pyx_ImportFunction_%s(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' + % (Naming.cyversion, entry.name, cname, sig)) for entry in api_vars: cname = env.mangle(Naming.varptr_prefix_api, entry.name) sig = entry.type.empty_declaration_code() h_code.putln( - 'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;' - % (entry.name, cname, sig)) + 'if (__Pyx_ImportVoidPtr_%s(module, "%s", (void **)&%s, "%s") < 0) goto bad;' + % (Naming.cyversion, entry.name, cname, sig)) with ModuleImportGenerator(h_code, imported_modules={env.qualified_name: 'module'}) as import_generator: for entry in api_extension_types: self.generate_type_import_call(entry.type, h_code, import_generator, error_code="goto bad;") @@ -2957,7 +2957,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): cname = module.mangle(Naming.varptr_prefix, entry.name) signature = entry.type.empty_declaration_code() code.putln( - 'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % ( + 'if (__Pyx_ImportVoidPtr_%s(%s, "%s", (void **)&%s, "%s") < 0) %s' % ( + Naming.cyversion, temp, entry.name, cname, signature, code.error_goto(self.pos))) code.put_decref_clear(temp, py_object_type) @@ -2982,7 +2983,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.put_gotref(temp) for entry in entries: code.putln( - 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % ( + 'if (__Pyx_ImportFunction_%s(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % ( + Naming.cyversion, temp, entry.name, entry.cname, @@ -3059,8 +3061,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): error_code = code.error_goto(error_pos) module = import_generator.imported_module(module_name, error_code) - code.put('%s = __Pyx_ImportType(%s, %s,' % ( + code.put('%s = __Pyx_ImportType_%s(%s, %s,' % ( type.typeptr_cname, + Naming.cyversion, module, module_name)) @@ -3078,12 +3081,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if not condition: code.putln("") # start in new line code.putln("#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000") - code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT(%s),' % (objstruct, objstruct)) + code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT_%s(%s),' % ( + objstruct, Naming.cyversion, objstruct)) code.putln("#else") - code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT(%s),' % (sizeof_objstruct, sizeof_objstruct)) + code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT_%s(%s),' % ( + sizeof_objstruct, Naming.cyversion, sizeof_objstruct)) code.putln("#endif") else: - code.putln('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT(%s),' % (objstruct, objstruct)) + code.put('sizeof(%s), __PYX_GET_STRUCT_ALIGNMENT_%s(%s),' % ( + objstruct, Naming.cyversion, objstruct)) # check_size if type.check_size and type.check_size in ('error', 'warn', 'ignore'): @@ -3093,7 +3099,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): else: raise RuntimeError("invalid value for check_size '%s' when compiling %s.%s" % ( type.check_size, module_name, type.name)) - code.putln('__Pyx_ImportType_CheckSize_%s);' % check_size.title()) + code.put('__Pyx_ImportType_CheckSize_%s_%s);' % ( + check_size.title(), Naming.cyversion)) code.putln(' if (!%s) %s' % (type.typeptr_cname, error_code)) diff --git a/Cython/Compiler/Naming.py b/Cython/Compiler/Naming.py index 2c9b62078..4dd6cbbd5 100644 --- a/Cython/Compiler/Naming.py +++ b/Cython/Compiler/Naming.py @@ -5,8 +5,10 @@ # Prefixes for generating C names. # Collected here to facilitate ensuring uniqueness. # +from .. import __version__ pyrex_prefix = "__pyx_" +cyversion = __version__.replace('.', '_') codewriter_temp_prefix = pyrex_prefix + "t_" diff --git a/Cython/Utility/ImportExport.c b/Cython/Utility/ImportExport.c index e1458fc8f..d6f06ecd7 100644 --- a/Cython/Utility/ImportExport.c +++ b/Cython/Utility/ImportExport.c @@ -8,7 +8,6 @@ #endif #endif - /////////////// Import.proto /////////////// static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/ @@ -297,37 +296,39 @@ set_path: /////////////// TypeImport.proto /////////////// +//@substitute: naming -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto +#ifndef __PYX_HAVE_RT_ImportType_proto_$cyversion +#define __PYX_HAVE_RT_ImportType_proto_$cyversion #if __STDC_VERSION__ >= 201112L #include #endif #if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L -#define __PYX_GET_STRUCT_ALIGNMENT(s) alignof(s) +#define __PYX_GET_STRUCT_ALIGNMENT_$cyversion(s) alignof(s) #else // best guess at what the alignment could be since we can't measure it -#define __PYX_GET_STRUCT_ALIGNMENT(s) sizeof(void*) +#define __PYX_GET_STRUCT_ALIGNMENT_$cyversion(s) sizeof(void*) #endif -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 +enum __Pyx_ImportType_CheckSize_$cyversion { + __Pyx_ImportType_CheckSize_Error_$cyversion = 0, + __Pyx_ImportType_CheckSize_Warn_$cyversion = 1, + __Pyx_ImportType_CheckSize_Ignore_$cyversion = 2 }; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize check_size); /*proto*/ +static PyTypeObject *__Pyx_ImportType_$cyversion(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_$cyversion check_size); /*proto*/ #endif /////////////// TypeImport /////////////// +//@substitute: naming -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize check_size) +#ifndef __PYX_HAVE_RT_ImportType_$cyversion +#define __PYX_HAVE_RT_ImportType_$cyversion +static PyTypeObject *__Pyx_ImportType_$cyversion(PyObject *module, const char *module_name, const char *class_name, + size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_$cyversion check_size) { PyObject *result = 0; char warning[200]; @@ -387,14 +388,14 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, module_name, class_name, size, basicsize); goto bad; } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + if (check_size == __Pyx_ImportType_CheckSize_Error_$cyversion && (size_t)basicsize != size) { PyErr_Format(PyExc_ValueError, "%.200s.%.200s size changed, may indicate binary incompatibility. " "Expected %zd from C header, got %zd from PyObject", module_name, class_name, size, basicsize); goto bad; } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + else if (check_size == __Pyx_ImportType_CheckSize_Warn_$cyversion && (size_t)basicsize > size) { PyOS_snprintf(warning, sizeof(warning), "%s.%s size changed, may indicate binary incompatibility. " "Expected %zd from C header, got %zd from PyObject", @@ -410,15 +411,16 @@ bad: #endif /////////////// FunctionImport.proto /////////////// +//@substitute: naming -static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/ +static int __Pyx_ImportFunction_$cyversion(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/ /////////////// FunctionImport /////////////// //@substitute: naming -#ifndef __PYX_HAVE_RT_ImportFunction -#define __PYX_HAVE_RT_ImportFunction -static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { +#ifndef __PYX_HAVE_RT_ImportFunction_$cyversion +#define __PYX_HAVE_RT_ImportFunction_$cyversion +static int __Pyx_ImportFunction_$cyversion(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { PyObject *d = 0; PyObject *cobj = 0; union { @@ -515,15 +517,16 @@ bad: } /////////////// VoidPtrImport.proto /////////////// +//@substitute: naming -static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig); /*proto*/ +static int __Pyx_ImportVoidPtr_$cyversion(PyObject *module, const char *name, void **p, const char *sig); /*proto*/ /////////////// VoidPtrImport /////////////// //@substitute: naming -#ifndef __PYX_HAVE_RT_ImportVoidPtr -#define __PYX_HAVE_RT_ImportVoidPtr -static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig) { +#ifndef __PYX_HAVE_RT_ImportVoidPtr_$cyversion +#define __PYX_HAVE_RT_ImportVoidPtr_$cyversion +static int __Pyx_ImportVoidPtr_$cyversion(PyObject *module, const char *name, void **p, const char *sig) { PyObject *d = 0; PyObject *cobj = 0; -- cgit v1.2.1