summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2021-09-28 08:48:12 +0100
committerGitHub <noreply@github.com>2021-09-28 09:48:12 +0200
commitdaa0a4434fa3ef281f9df65f7bb6098d31e1e400 (patch)
tree13afc9b5924250a0632290d5db7d0e3038c6eccd
parentfa8db66368a9527c8df441a0bbfee714eb795930 (diff)
downloadcython-daa0a4434fa3ef281f9df65f7bb6098d31e1e400.tar.gz
Fix the name of attributes in the common ABI module (GH-4376)
Attribute names used to be fully qualified like "_cython_3_0_0a9.cython_function_or_method" instead of the plain name. Closes https://github.com/cython/cython/issues/4373
-rw-r--r--Cython/Utility/CommonStructures.c20
-rw-r--r--tests/run/common_utility_types.srctree13
2 files changed, 27 insertions, 6 deletions
diff --git a/Cython/Utility/CommonStructures.c b/Cython/Utility/CommonStructures.c
index c596e15bb..34778e341 100644
--- a/Cython/Utility/CommonStructures.c
+++ b/Cython/Utility/CommonStructures.c
@@ -8,6 +8,7 @@ static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec
/////////////// FetchCommonType ///////////////
//@requires:ExtensionTypes.c::FixUpExtensionType
+//@requires:StringTools.c::IncludeStringH
static PyObject *__Pyx_FetchSharedCythonABIModule(void) {
PyObject *abi_module = PyImport_AddModule((char*) __PYX_ABI_MODULE_NAME);
@@ -37,15 +38,19 @@ static int __Pyx_VerifyCachedType(PyObject *cached_type,
#if !CYTHON_USE_TYPE_SPECS
static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
PyObject* abi_module;
+ const char* object_name;
PyTypeObject *cached_type = NULL;
abi_module = __Pyx_FetchSharedCythonABIModule();
if (!abi_module) return NULL;
- cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, type->tp_name);
+ // get the final part of the object name (after the last dot)
+ object_name = strrchr(type->tp_name, '.');
+ object_name = object_name ? object_name+1 : type->tp_name;
+ cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name);
if (cached_type) {
if (__Pyx_VerifyCachedType(
(PyObject *)cached_type,
- type->tp_name,
+ object_name,
cached_type->tp_basicsize,
type->tp_basicsize) < 0) {
goto bad;
@@ -56,7 +61,7 @@ static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
PyErr_Clear();
if (PyType_Ready(type) < 0) goto bad;
- if (PyObject_SetAttrString(abi_module, type->tp_name, (PyObject *)type) < 0)
+ if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0)
goto bad;
Py_INCREF(type);
cached_type = type;
@@ -75,11 +80,14 @@ bad:
static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) {
PyObject *abi_module, *cached_type = NULL;
+ // get the final part of the object name (after the last dot)
+ const char* object_name = strrchr(spec->name, '.');
+ object_name = object_name ? object_name+1 : spec->name;
abi_module = __Pyx_FetchSharedCythonABIModule();
if (!abi_module) return NULL;
- cached_type = PyObject_GetAttrString(abi_module, spec->name);
+ cached_type = PyObject_GetAttrString(abi_module, object_name);
if (cached_type) {
Py_ssize_t basicsize;
#if CYTHON_COMPILING_IN_LIMITED_API
@@ -95,7 +103,7 @@ static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec
#endif
if (__Pyx_VerifyCachedType(
cached_type,
- spec->name,
+ object_name,
basicsize,
spec->basicsize) < 0) {
goto bad;
@@ -110,7 +118,7 @@ static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec
cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases);
if (unlikely(!cached_type)) goto bad;
if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad;
- if (PyObject_SetAttrString(abi_module, spec->name, cached_type) < 0) goto bad;
+ if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad;
done:
Py_DECREF(abi_module);
diff --git a/tests/run/common_utility_types.srctree b/tests/run/common_utility_types.srctree
index 35daad505..e978accc3 100644
--- a/tests/run/common_utility_types.srctree
+++ b/tests/run/common_utility_types.srctree
@@ -36,3 +36,16 @@ assert type(a.funcA) is type(b.funcB)
assert a.funcA.func_globals is a.__dict__
assert b.funcB.func_globals is b.__dict__
+
+# Test that it's possible to look up the name of the class
+from sys import modules
+cy_modules = [ mod for n, mod in modules.items() if n.startswith("_cython_") ]
+# In principle it's possible to have "_cython_" internal modules for multiple
+# different versions of Cython. However, since this is run in an end-to-end test
+# with a very short list of imports it should not happen here.
+assert(len(cy_modules)==1)
+mod = cy_modules[0]
+
+assert '.' not in type(a.funcA).__name__
+func_t = getattr(mod, type(a.funcA).__name__)
+assert func_t is type(a.funcA)