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