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().
This commit is contained in:
Victor Stinner 2023-06-21 16:35:58 +02:00 committed by GitHub
parent 2178bbc121
commit fc32522b08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 24 additions and 13 deletions

View File

@ -3,18 +3,19 @@
#include "Python.h" #include "Python.h"
#include "pycore_call.h" #include "pycore_call.h"
#include "pycore_code.h" // CO_FAST_FREE #include "pycore_code.h" // CO_FAST_FREE
#include "pycore_symtable.h" // _Py_Mangle()
#include "pycore_dict.h" // _PyDict_KeysSize() #include "pycore_dict.h" // _PyDict_KeysSize()
#include "pycore_frame.h" // _PyInterpreterFrame
#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_long.h" // _PyLong_IsNegative()
#include "pycore_memoryobject.h" // _PyMemoryView_FromBufferProc() #include "pycore_memoryobject.h" // _PyMemoryView_FromBufferProc()
#include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_moduleobject.h" // _PyModule_GetDef()
#include "pycore_object.h" // _PyType_HasFeature() #include "pycore_object.h" // _PyType_HasFeature()
#include "pycore_long.h" // _PyLong_IsNegative()
#include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_symtable.h" // _Py_Mangle()
#include "pycore_typeobject.h" // struct type_cache #include "pycore_typeobject.h" // struct type_cache
#include "pycore_unionobject.h" // _Py_union_type_or #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 "opcode.h" // MAKE_CELL
#include "structmember.h" // PyMemberDef #include "structmember.h" // PyMemberDef
@ -75,13 +76,10 @@ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value);
static inline PyTypeObject * static inline PyTypeObject *
type_from_ref(PyObject *ref) type_from_ref(PyObject *ref)
{ {
assert(PyWeakref_CheckRef(ref)); PyObject *obj = _PyWeakref_GET_REF(ref);
PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref if (obj == NULL) {
assert(obj != NULL);
if (obj == Py_None) {
return NULL; return NULL;
} }
assert(PyType_Check(obj));
return _PyType_CAST(obj); return _PyType_CAST(obj);
} }
@ -450,15 +448,17 @@ _PyType_GetSubclasses(PyTypeObject *self)
Py_ssize_t i = 0; Py_ssize_t i = 0;
PyObject *ref; // borrowed ref PyObject *ref; // borrowed ref
while (PyDict_Next(subclasses, &i, NULL, &ref)) { while (PyDict_Next(subclasses, &i, NULL, &ref)) {
PyTypeObject *subclass = type_from_ref(ref); // borrowed PyTypeObject *subclass = type_from_ref(ref);
if (subclass == NULL) { if (subclass == NULL) {
continue; continue;
} }
if (PyList_Append(list, _PyObject_CAST(subclass)) < 0) { if (PyList_Append(list, _PyObject_CAST(subclass)) < 0) {
Py_DECREF(list); Py_DECREF(list);
Py_DECREF(subclass);
return NULL; return NULL;
} }
Py_DECREF(subclass);
} }
return list; return list;
} }
@ -778,11 +778,12 @@ PyType_Modified(PyTypeObject *type)
Py_ssize_t i = 0; Py_ssize_t i = 0;
PyObject *ref; PyObject *ref;
while (PyDict_Next(subclasses, &i, NULL, &ref)) { while (PyDict_Next(subclasses, &i, NULL, &ref)) {
PyTypeObject *subclass = type_from_ref(ref); // borrowed PyTypeObject *subclass = type_from_ref(ref);
if (subclass == NULL) { if (subclass == NULL) {
continue; continue;
} }
PyType_Modified(subclass); PyType_Modified(subclass);
Py_DECREF(subclass);
} }
} }
@ -4989,12 +4990,13 @@ clear_static_tp_subclasses(PyTypeObject *type)
Py_ssize_t i = 0; Py_ssize_t i = 0;
PyObject *key, *ref; // borrowed ref PyObject *key, *ref; // borrowed ref
while (PyDict_Next(subclasses, &i, &key, &ref)) { while (PyDict_Next(subclasses, &i, &key, &ref)) {
PyTypeObject *subclass = type_from_ref(ref); // borrowed PyTypeObject *subclass = type_from_ref(ref);
if (subclass == NULL) { if (subclass == NULL) {
continue; continue;
} }
// All static builtin subtypes should have been finalized already. // All static builtin subtypes should have been finalized already.
assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
Py_DECREF(subclass);
} }
clear_tp_subclasses(type); clear_tp_subclasses(type);
@ -7636,10 +7638,15 @@ get_subclasses_key(PyTypeObject *type, PyTypeObject *base)
PyObject *subclasses = lookup_tp_subclasses(base); PyObject *subclasses = lookup_tp_subclasses(base);
if (subclasses != NULL) { if (subclasses != NULL) {
while (PyDict_Next(subclasses, &i, &key, &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;
}
if (subclass == type) { if (subclass == type) {
Py_DECREF(subclass);
return Py_NewRef(key); return Py_NewRef(key);
} }
Py_DECREF(subclass);
} }
} }
/* It wasn't found. */ /* It wasn't found. */
@ -10035,7 +10042,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
Py_ssize_t i = 0; Py_ssize_t i = 0;
PyObject *ref; PyObject *ref;
while (PyDict_Next(subclasses, &i, NULL, &ref)) { while (PyDict_Next(subclasses, &i, NULL, &ref)) {
PyTypeObject *subclass = type_from_ref(ref); // borrowed PyTypeObject *subclass = type_from_ref(ref);
if (subclass == NULL) { if (subclass == NULL) {
continue; continue;
} }
@ -10045,16 +10052,20 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
if (dict != NULL && PyDict_Check(dict)) { if (dict != NULL && PyDict_Check(dict)) {
int r = PyDict_Contains(dict, attr_name); int r = PyDict_Contains(dict, attr_name);
if (r < 0) { if (r < 0) {
Py_DECREF(subclass);
return -1; return -1;
} }
if (r > 0) { if (r > 0) {
Py_DECREF(subclass);
continue; continue;
} }
} }
if (update_subclasses(subclass, attr_name, callback, data) < 0) { if (update_subclasses(subclass, attr_name, callback, data) < 0) {
Py_DECREF(subclass);
return -1; return -1;
} }
Py_DECREF(subclass);
} }
return 0; return 0;
} }