1 /////////////// FetchCommonType.proto ///////////////
2
3 #if !CYTHON_USE_TYPE_SPECS
4 static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
5 #else
6 static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases);
7 #endif
8
9 /////////////// FetchCommonType ///////////////
10 //@requires:ExtensionTypes.c::FixUpExtensionType
11 //@requires:StringTools.c::IncludeStringH
12
__Pyx_FetchSharedCythonABIModule(void)13 static PyObject *__Pyx_FetchSharedCythonABIModule(void) {
14 PyObject *abi_module = PyImport_AddModule((char*) __PYX_ABI_MODULE_NAME);
15 if (!abi_module) return NULL;
16 Py_INCREF(abi_module);
17 return abi_module;
18 }
19
__Pyx_VerifyCachedType(PyObject * cached_type,const char * name,Py_ssize_t basicsize,Py_ssize_t expected_basicsize)20 static int __Pyx_VerifyCachedType(PyObject *cached_type,
21 const char *name,
22 Py_ssize_t basicsize,
23 Py_ssize_t expected_basicsize) {
24 if (!PyType_Check(cached_type)) {
25 PyErr_Format(PyExc_TypeError,
26 "Shared Cython type %.200s is not a type object", name);
27 return -1;
28 }
29 if (basicsize != expected_basicsize) {
30 PyErr_Format(PyExc_TypeError,
31 "Shared Cython type %.200s has the wrong size, try recompiling",
32 name);
33 return -1;
34 }
35 return 0;
36 }
37
38 #if !CYTHON_USE_TYPE_SPECS
__Pyx_FetchCommonType(PyTypeObject * type)39 static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
40 PyObject* abi_module;
41 const char* object_name;
42 PyTypeObject *cached_type = NULL;
43
44 abi_module = __Pyx_FetchSharedCythonABIModule();
45 if (!abi_module) return NULL;
46 // get the final part of the object name (after the last dot)
47 object_name = strrchr(type->tp_name, '.');
48 object_name = object_name ? object_name+1 : type->tp_name;
49 cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name);
50 if (cached_type) {
51 if (__Pyx_VerifyCachedType(
52 (PyObject *)cached_type,
53 object_name,
54 cached_type->tp_basicsize,
55 type->tp_basicsize) < 0) {
56 goto bad;
57 }
58 goto done;
59 }
60
61 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
62 PyErr_Clear();
63 if (PyType_Ready(type) < 0) goto bad;
64 if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0)
65 goto bad;
66 Py_INCREF(type);
67 cached_type = type;
68
69 done:
70 Py_DECREF(abi_module);
71 // NOTE: always returns owned reference, or NULL on error
72 return cached_type;
73
74 bad:
75 Py_XDECREF(cached_type);
76 cached_type = NULL;
77 goto done;
78 }
79 #else
80
__Pyx_FetchCommonTypeFromSpec(PyObject * module,PyType_Spec * spec,PyObject * bases)81 static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) {
82 PyObject *abi_module, *cached_type = NULL;
83 // get the final part of the object name (after the last dot)
84 const char* object_name = strrchr(spec->name, '.');
85 object_name = object_name ? object_name+1 : spec->name;
86
87 abi_module = __Pyx_FetchSharedCythonABIModule();
88 if (!abi_module) return NULL;
89
90 cached_type = PyObject_GetAttrString(abi_module, object_name);
91 if (cached_type) {
92 Py_ssize_t basicsize;
93 #if CYTHON_COMPILING_IN_LIMITED_API
94 PyObject *py_basicsize;
95 py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__");
96 if (unlikely(!py_basicsize)) goto bad;
97 basicsize = PyLong_AsSsize_t(py_basicsize);
98 Py_DECREF(py_basicsize);
99 py_basicsize = 0;
100 if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
101 #else
102 basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1;
103 #endif
104 if (__Pyx_VerifyCachedType(
105 cached_type,
106 object_name,
107 basicsize,
108 spec->basicsize) < 0) {
109 goto bad;
110 }
111 goto done;
112 }
113
114 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
115 PyErr_Clear();
116 // We pass the ABI module reference to avoid keeping the user module alive by foreign type usages.
117 (void) module;
118 cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases);
119 if (unlikely(!cached_type)) goto bad;
120 if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad;
121 if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad;
122
123 done:
124 Py_DECREF(abi_module);
125 // NOTE: always returns owned reference, or NULL on error
126 assert(cached_type == NULL || PyType_Check(cached_type));
127 return (PyTypeObject *) cached_type;
128
129 bad:
130 Py_XDECREF(cached_type);
131 cached_type = NULL;
132 goto done;
133 }
134 #endif
135
136