From fc32522b081c895f3798e4a16788b800cff08166 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 21 Jun 2023 16:35:58 +0200 Subject: [PATCH] gh-105927: type_from_ref() uses _PyWeakref_GET_REF() (#105963) type_from_ref() now returns a strong reference to the type, instead of a borrowed reference: replace PyWeakref_GET_OBJECT() with _PyWeakref_GET_REF(). --- Objects/typeobject.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5d29d262575..cbba6f0fa80 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3,18 +3,19 @@ #include "Python.h" #include "pycore_call.h" #include "pycore_code.h" // CO_FAST_FREE -#include "pycore_symtable.h" // _Py_Mangle() #include "pycore_dict.h" // _PyDict_KeysSize() +#include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_long.h" // _PyLong_IsNegative() #include "pycore_memoryobject.h" // _PyMemoryView_FromBufferProc() #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_object.h" // _PyType_HasFeature() -#include "pycore_long.h" // _PyLong_IsNegative() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_symtable.h" // _Py_Mangle() #include "pycore_typeobject.h" // struct type_cache #include "pycore_unionobject.h" // _Py_union_type_or -#include "pycore_frame.h" // _PyInterpreterFrame +#include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "opcode.h" // MAKE_CELL #include "structmember.h" // PyMemberDef @@ -75,13 +76,10 @@ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value); static inline PyTypeObject * type_from_ref(PyObject *ref) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref - assert(obj != NULL); - if (obj == Py_None) { + PyObject *obj = _PyWeakref_GET_REF(ref); + if (obj == NULL) { return NULL; } - assert(PyType_Check(obj)); return _PyType_CAST(obj); } @@ -450,15 +448,17 @@ _PyType_GetSubclasses(PyTypeObject *self) Py_ssize_t i = 0; PyObject *ref; // borrowed ref while (PyDict_Next(subclasses, &i, NULL, &ref)) { - PyTypeObject *subclass = type_from_ref(ref); // borrowed + PyTypeObject *subclass = type_from_ref(ref); if (subclass == NULL) { continue; } if (PyList_Append(list, _PyObject_CAST(subclass)) < 0) { Py_DECREF(list); + Py_DECREF(subclass); return NULL; } + Py_DECREF(subclass); } return list; } @@ -778,11 +778,12 @@ PyType_Modified(PyTypeObject *type) Py_ssize_t i = 0; PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - PyTypeObject *subclass = type_from_ref(ref); // borrowed + PyTypeObject *subclass = type_from_ref(ref); if (subclass == NULL) { continue; } PyType_Modified(subclass); + Py_DECREF(subclass); } } @@ -4989,12 +4990,13 @@ clear_static_tp_subclasses(PyTypeObject *type) Py_ssize_t i = 0; PyObject *key, *ref; // borrowed ref while (PyDict_Next(subclasses, &i, &key, &ref)) { - PyTypeObject *subclass = type_from_ref(ref); // borrowed + PyTypeObject *subclass = type_from_ref(ref); if (subclass == NULL) { continue; } // All static builtin subtypes should have been finalized already. assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + Py_DECREF(subclass); } clear_tp_subclasses(type); @@ -7636,10 +7638,15 @@ get_subclasses_key(PyTypeObject *type, PyTypeObject *base) PyObject *subclasses = lookup_tp_subclasses(base); if (subclasses != NULL) { while (PyDict_Next(subclasses, &i, &key, &ref)) { - PyTypeObject *subclass = type_from_ref(ref); // borrowed + PyTypeObject *subclass = type_from_ref(ref); + if (subclass == NULL) { + continue; + } if (subclass == type) { + Py_DECREF(subclass); return Py_NewRef(key); } + Py_DECREF(subclass); } } /* It wasn't found. */ @@ -10035,7 +10042,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, Py_ssize_t i = 0; PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - PyTypeObject *subclass = type_from_ref(ref); // borrowed + PyTypeObject *subclass = type_from_ref(ref); if (subclass == NULL) { continue; } @@ -10045,16 +10052,20 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, if (dict != NULL && PyDict_Check(dict)) { int r = PyDict_Contains(dict, attr_name); if (r < 0) { + Py_DECREF(subclass); return -1; } if (r > 0) { + Py_DECREF(subclass); continue; } } if (update_subclasses(subclass, attr_name, callback, data) < 0) { + Py_DECREF(subclass); return -1; } + Py_DECREF(subclass); } return 0; }