// Precalculates count of non-unique slots and fills wrapperbase.name_count.
extern int _PyType_InitSlotDefs(PyInterpreterState *interp);
+// Like PyType_GetBaseByToken, but does not modify refcounts.
+// Cannot fail; arguments must be valid.
+PyAPI_FUNC(int)
+_PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **result);
+
#ifdef __cplusplus
}
#endif
return _stginfo_from_type(state, Py_TYPE(obj), result);
}
-/* A variant of PyStgInfo_FromType that doesn't need the state,
+/* A variant of PyStgInfo_FromType that doesn't need the state
+ * and doesn't modify any refcounts,
* so it can be called from finalization functions when the module
* state is torn down.
*/
_PyStgInfo_FromType_NoState(PyObject *type)
{
PyTypeObject *PyCType_Type;
- if (PyType_GetBaseByToken(Py_TYPE(type), &pyctype_type_spec, &PyCType_Type) < 0) {
- return NULL;
- }
- if (PyCType_Type == NULL) {
- PyErr_Format(PyExc_TypeError, "expected a ctypes type, got '%N'", type);
+ if (_PyType_GetBaseByToken_Borrow(Py_TYPE(type), &pyctype_type_spec, &PyCType_Type) < 0 ||
+ PyCType_Type == NULL) {
return NULL;
}
- StgInfo *info = PyObject_GetTypeData(type, PyCType_Type);
- Py_DECREF(PyCType_Type);
- return info;
+ return PyObject_GetTypeData(type, PyCType_Type);
}
// Initialize StgInfo on a newly created type
}
int
-PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
+_PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **result)
{
+ assert(token != NULL);
+ assert(PyType_Check(type));
+
if (result != NULL) {
*result = NULL;
}
- if (token == NULL) {
- PyErr_Format(PyExc_SystemError,
- "PyType_GetBaseByToken called with token=NULL");
- return -1;
- }
- if (!PyType_Check(type)) {
- PyErr_Format(PyExc_TypeError,
- "expected a type, got a '%T' object", type);
- return -1;
- }
-
if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
// No static type has a heaptype superclass,
// which is ensured by type_ready_mro().
if (((PyHeapTypeObject*)type)->ht_token == token) {
found:
if (result != NULL) {
- *result = (PyTypeObject *)Py_NewRef(type);
+ *result = type;
}
return 1;
}
return 0;
}
+int
+PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
+{
+ if (result != NULL) {
+ *result = NULL;
+ }
+ if (token == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "PyType_GetBaseByToken called with token=NULL");
+ return -1;
+ }
+ if (!PyType_Check(type)) {
+ PyErr_Format(PyExc_TypeError,
+ "expected a type, got a '%T' object", type);
+ return -1;
+ }
+
+ int res = _PyType_GetBaseByToken_Borrow(type, token, result);
+ if (res > 0 && result) {
+ Py_INCREF(*result);
+ }
+ return res;
+}
+
void *
PyObject_GetTypeData(PyObject *obj, PyTypeObject *cls)