Skip to content

Commit f8648ab

Browse files
authored
Merge pull request #2 from encukou/dont_modify_refcount
_PyType_GetBaseByToken_Borrow can't fail; adjust comments
2 parents f860118 + 37f8fbf commit f8648ab

File tree

4 files changed

+20
-12
lines changed

4 files changed

+20
-12
lines changed

Include/internal/pycore_typeobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ extern int _PyType_CacheGetItemForSpecialization(PyHeapTypeObject *ht, PyObject
155155
// Precalculates count of non-unique slots and fills wrapperbase.name_count.
156156
extern int _PyType_InitSlotDefs(PyInterpreterState *interp);
157157

158+
// Like PyType_GetBaseByToken, but does not modify refcounts.
159+
// Cannot fail; arguments must be valid.
158160
PyAPI_FUNC(int)
159161
_PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **result);
160162

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Avoid reference count operations in garbage collection of :mod:`ctypes`
2+
objects.

Modules/_ctypes/ctypes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,8 @@ PyStgInfo_FromAny(ctypes_state *state, PyObject *obj, StgInfo **result)
608608
return _stginfo_from_type(state, Py_TYPE(obj), result);
609609
}
610610

611-
/* A variant of PyStgInfo_FromType that doesn't need the state,
611+
/* A variant of PyStgInfo_FromType that doesn't need the state
612+
* and doesn't modify any refcounts,
612613
* so it can be called from finalization functions when the module
613614
* state is torn down.
614615
*/

Objects/typeobject.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5879,21 +5879,13 @@ get_base_by_token_recursive(PyObject *bases, void *token)
58795879
int
58805880
_PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **result)
58815881
{
5882+
assert(token != NULL);
5883+
assert(PyType_Check(type));
5884+
58825885
if (result != NULL) {
58835886
*result = NULL;
58845887
}
58855888

5886-
if (token == NULL) {
5887-
PyErr_Format(PyExc_SystemError,
5888-
"PyType_GetBaseByToken called with token=NULL");
5889-
return -1;
5890-
}
5891-
if (!PyType_Check(type)) {
5892-
PyErr_Format(PyExc_TypeError,
5893-
"expected a type, got a '%T' object", type);
5894-
return -1;
5895-
}
5896-
58975889
if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
58985890
// No static type has a heaptype superclass,
58995891
// which is ensured by type_ready_mro().
@@ -5939,6 +5931,17 @@ _PyType_GetBaseByToken_Borrow(PyTypeObject *type, void *token, PyTypeObject **re
59395931
int
59405932
PyType_GetBaseByToken(PyTypeObject *type, void *token, PyTypeObject **result)
59415933
{
5934+
if (token == NULL) {
5935+
PyErr_Format(PyExc_SystemError,
5936+
"PyType_GetBaseByToken called with token=NULL");
5937+
return -1;
5938+
}
5939+
if (!PyType_Check(type)) {
5940+
PyErr_Format(PyExc_TypeError,
5941+
"expected a type, got a '%T' object", type);
5942+
return -1;
5943+
}
5944+
59425945
int res = _PyType_GetBaseByToken_Borrow(type, token, result);
59435946
if (res > 0 && result) {
59445947
Py_INCREF(*result);

0 commit comments

Comments
 (0)