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 "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;
}