gh-111789: Use PyDict_GetItemRef() in Objects/ (GH-111827)

This commit is contained in:
Serhiy Storchaka 2023-11-14 11:25:39 +02:00 committed by GitHub
parent e31d65e0b7
commit 18203a6bc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 120 deletions

View File

@ -204,12 +204,7 @@ int
PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result) PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
{ {
if (PyDict_CheckExact(obj)) { if (PyDict_CheckExact(obj)) {
*result = PyDict_GetItemWithError(obj, key); /* borrowed */ return PyDict_GetItemRef(obj, key, result);
if (*result) {
Py_INCREF(*result);
return 1;
}
return PyErr_Occurred() ? -1 : 0;
} }
*result = PyObject_GetItem(obj, key); *result = PyObject_GetItem(obj, key);

View File

@ -92,8 +92,8 @@ PyFunction_ClearWatcher(int watcher_id)
PyFunctionObject * PyFunctionObject *
_PyFunction_FromConstructor(PyFrameConstructor *constr) _PyFunction_FromConstructor(PyFrameConstructor *constr)
{ {
PyObject *module = Py_XNewRef(PyDict_GetItemWithError(constr->fc_globals, &_Py_ID(__name__))); PyObject *module;
if (!module && PyErr_Occurred()) { if (PyDict_GetItemRef(constr->fc_globals, &_Py_ID(__name__), &module) < 0) {
return NULL; return NULL;
} }
@ -158,12 +158,11 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
Py_INCREF(doc); Py_INCREF(doc);
// __module__: Use globals['__name__'] if it exists, or NULL. // __module__: Use globals['__name__'] if it exists, or NULL.
PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); PyObject *module;
PyObject *builtins = NULL; PyObject *builtins = NULL;
if (module == NULL && _PyErr_Occurred(tstate)) { if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &module) < 0) {
goto error; goto error;
} }
Py_XINCREF(module);
builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
if (builtins == NULL) { if (builtins == NULL) {

View File

@ -522,6 +522,7 @@ PyModule_GetNameObject(PyObject *mod)
} }
PyObject *name; PyObject *name;
if (PyDict_GetItemRef(dict, &_Py_ID(__name__), &name) <= 0) { if (PyDict_GetItemRef(dict, &_Py_ID(__name__), &name) <= 0) {
// error or not found
goto error; goto error;
} }
if (!PyUnicode_Check(name)) { if (!PyUnicode_Check(name)) {
@ -562,6 +563,7 @@ PyModule_GetFilenameObject(PyObject *mod)
} }
PyObject *fileobj; PyObject *fileobj;
if (PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj) <= 0) { if (PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj) <= 0) {
// error or not found
goto error; goto error;
} }
if (!PyUnicode_Check(fileobj)) { if (!PyUnicode_Check(fileobj)) {
@ -816,28 +818,28 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
PyErr_Clear(); PyErr_Clear();
} }
assert(m->md_dict != NULL); assert(m->md_dict != NULL);
getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__)); if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__getattr__), &getattr) < 0) {
return NULL;
}
if (getattr) { if (getattr) {
PyObject *result = PyObject_CallOneArg(getattr, name); PyObject *result = PyObject_CallOneArg(getattr, name);
if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) { if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
// suppress AttributeError // suppress AttributeError
PyErr_Clear(); PyErr_Clear();
} }
Py_DECREF(getattr);
return result; return result;
} }
if (PyErr_Occurred()) { if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__name__), &mod_name) < 0) {
return NULL; return NULL;
} }
mod_name = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__name__));
if (mod_name && PyUnicode_Check(mod_name)) { if (mod_name && PyUnicode_Check(mod_name)) {
Py_INCREF(mod_name); PyObject *spec;
PyObject *spec = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__spec__)); if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__spec__), &spec) < 0) {
if (spec == NULL && PyErr_Occurred()) {
Py_DECREF(mod_name); Py_DECREF(mod_name);
return NULL; return NULL;
} }
if (suppress != 1) { if (suppress != 1) {
Py_XINCREF(spec);
if (_PyModuleSpec_IsInitializing(spec)) { if (_PyModuleSpec_IsInitializing(spec)) {
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"partially initialized " "partially initialized "
@ -856,14 +858,12 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
"module '%U' has no attribute '%U'", "module '%U' has no attribute '%U'",
mod_name, name); mod_name, name);
} }
Py_XDECREF(spec);
} }
Py_XDECREF(spec);
Py_DECREF(mod_name); Py_DECREF(mod_name);
return NULL; return NULL;
} }
else if (PyErr_Occurred()) { Py_XDECREF(mod_name);
return NULL;
}
if (suppress != 1) { if (suppress != 1) {
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"module has no attribute '%U'", name); "module has no attribute '%U'", name);
@ -957,11 +957,8 @@ module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
return NULL; return NULL;
} }
PyObject *annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); PyObject *annotations;
if (annotations) { if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) == 0) {
Py_INCREF(annotations);
}
else if (!PyErr_Occurred()) {
annotations = PyDict_New(); annotations = PyDict_New();
if (annotations) { if (annotations) {
int result = PyDict_SetItem( int result = PyDict_SetItem(

View File

@ -1490,19 +1490,14 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
} }
if (dict != NULL) { if (dict != NULL) {
Py_INCREF(dict); Py_INCREF(dict);
PyObject *attr = PyDict_GetItemWithError(dict, name); if (PyDict_GetItemRef(dict, name, method) != 0) {
if (attr != NULL) { // found or error
*method = Py_NewRef(attr);
Py_DECREF(dict); Py_DECREF(dict);
Py_XDECREF(descr); Py_XDECREF(descr);
return 0; return 0;
} }
// not found
Py_DECREF(dict); Py_DECREF(dict);
if (PyErr_Occurred()) {
Py_XDECREF(descr);
return 0;
}
} }
if (meth_found) { if (meth_found) {
@ -1607,21 +1602,17 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name,
} }
if (dict != NULL) { if (dict != NULL) {
Py_INCREF(dict); Py_INCREF(dict);
res = PyDict_GetItemWithError(dict, name); int rc = PyDict_GetItemRef(dict, name, &res);
Py_DECREF(dict);
if (res != NULL) { if (res != NULL) {
Py_INCREF(res);
Py_DECREF(dict);
goto done; goto done;
} }
else { else if (rc < 0) {
Py_DECREF(dict); if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) {
if (PyErr_Occurred()) { PyErr_Clear();
if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) { }
PyErr_Clear(); else {
} goto done;
else {
goto done;
}
} }
} }
} }

View File

@ -1092,14 +1092,9 @@ type_module(PyTypeObject *type, void *context)
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
PyObject *dict = lookup_tp_dict(type); PyObject *dict = lookup_tp_dict(type);
mod = PyDict_GetItemWithError(dict, &_Py_ID(__module__)); if (PyDict_GetItemRef(dict, &_Py_ID(__module__), &mod) == 0) {
if (mod == NULL) { PyErr_Format(PyExc_AttributeError, "__module__");
if (!PyErr_Occurred()) {
PyErr_Format(PyExc_AttributeError, "__module__");
}
return NULL;
} }
Py_INCREF(mod);
} }
else { else {
const char *s = strrchr(type->tp_name, '.'); const char *s = strrchr(type->tp_name, '.');
@ -1134,17 +1129,16 @@ type_abstractmethods(PyTypeObject *type, void *context)
PyObject *mod = NULL; PyObject *mod = NULL;
/* type itself has an __abstractmethods__ descriptor (this). Don't return /* type itself has an __abstractmethods__ descriptor (this). Don't return
that. */ that. */
if (type != &PyType_Type) { if (type == &PyType_Type) {
PyObject *dict = lookup_tp_dict(type); PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__));
mod = PyDict_GetItemWithError(dict, &_Py_ID(__abstractmethods__));
} }
if (!mod) { else {
if (!PyErr_Occurred()) { PyObject *dict = lookup_tp_dict(type);
if (PyDict_GetItemRef(dict, &_Py_ID(__abstractmethods__), &mod) == 0) {
PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__));
} }
return NULL;
} }
return Py_NewRef(mod); return mod;
} }
static int static int
@ -1435,19 +1429,15 @@ type_get_doc(PyTypeObject *type, void *context)
return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc);
} }
PyObject *dict = lookup_tp_dict(type); PyObject *dict = lookup_tp_dict(type);
result = PyDict_GetItemWithError(dict, &_Py_ID(__doc__)); if (PyDict_GetItemRef(dict, &_Py_ID(__doc__), &result) == 0) {
if (result == NULL) { result = Py_NewRef(Py_None);
if (!PyErr_Occurred()) { }
result = Py_NewRef(Py_None); else if (result) {
descrgetfunc descr_get = Py_TYPE(result)->tp_descr_get;
if (descr_get) {
Py_SETREF(result, descr_get(result, NULL, (PyObject *)type));
} }
} }
else if (Py_TYPE(result)->tp_descr_get) {
result = Py_TYPE(result)->tp_descr_get(result, NULL,
(PyObject *)type);
}
else {
Py_INCREF(result);
}
return result; return result;
} }
@ -1477,16 +1467,16 @@ type_get_annotations(PyTypeObject *type, void *context)
PyObject *annotations; PyObject *annotations;
PyObject *dict = lookup_tp_dict(type); PyObject *dict = lookup_tp_dict(type);
annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) < 0) {
return NULL;
}
if (annotations) { if (annotations) {
if (Py_TYPE(annotations)->tp_descr_get) { descrgetfunc get = Py_TYPE(annotations)->tp_descr_get;
annotations = Py_TYPE(annotations)->tp_descr_get( if (get) {
annotations, NULL, (PyObject *)type); Py_SETREF(annotations, get(annotations, NULL, (PyObject *)type));
} else {
Py_INCREF(annotations);
} }
} }
else if (!PyErr_Occurred()) { else {
annotations = PyDict_New(); annotations = PyDict_New();
if (annotations) { if (annotations) {
int result = PyDict_SetItem( int result = PyDict_SetItem(
@ -1533,16 +1523,11 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
static PyObject * static PyObject *
type_get_type_params(PyTypeObject *type, void *context) type_get_type_params(PyTypeObject *type, void *context)
{ {
PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__)); PyObject *params;
if (PyDict_GetItemRef(lookup_tp_dict(type), &_Py_ID(__type_params__), &params) == 0) {
if (params) { return PyTuple_New(0);
return Py_NewRef(params);
} }
if (PyErr_Occurred()) { return params;
return NULL;
}
return PyTuple_New(0);
} }
static int static int
@ -3436,18 +3421,13 @@ type_new_set_module(PyTypeObject *type)
return 0; return 0;
} }
PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); PyObject *module;
if (module == NULL) { r = PyDict_GetItemRef(globals, &_Py_ID(__name__), &module);
if (PyErr_Occurred()) { if (module) {
return -1; r = PyDict_SetItem(dict, &_Py_ID(__module__), module);
} Py_DECREF(module);
return 0;
} }
return r;
if (PyDict_SetItem(dict, &_Py_ID(__module__), module) < 0) {
return -1;
}
return 0;
} }
@ -3458,23 +3438,24 @@ type_new_set_ht_name(PyTypeObject *type)
{ {
PyHeapTypeObject *et = (PyHeapTypeObject *)type; PyHeapTypeObject *et = (PyHeapTypeObject *)type;
PyObject *dict = lookup_tp_dict(type); PyObject *dict = lookup_tp_dict(type);
PyObject *qualname = PyDict_GetItemWithError(dict, &_Py_ID(__qualname__)); PyObject *qualname;
if (PyDict_GetItemRef(dict, &_Py_ID(__qualname__), &qualname) < 0) {
return -1;
}
if (qualname != NULL) { if (qualname != NULL) {
if (!PyUnicode_Check(qualname)) { if (!PyUnicode_Check(qualname)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"type __qualname__ must be a str, not %s", "type __qualname__ must be a str, not %s",
Py_TYPE(qualname)->tp_name); Py_TYPE(qualname)->tp_name);
Py_DECREF(qualname);
return -1; return -1;
} }
et->ht_qualname = Py_NewRef(qualname); et->ht_qualname = qualname;
if (PyDict_DelItem(dict, &_Py_ID(__qualname__)) < 0) { if (PyDict_DelItem(dict, &_Py_ID(__qualname__)) < 0) {
return -1; return -1;
} }
} }
else { else {
if (PyErr_Occurred()) {
return -1;
}
et->ht_qualname = Py_NewRef(et->ht_name); et->ht_qualname = Py_NewRef(et->ht_name);
} }
return 0; return 0;
@ -5888,24 +5869,22 @@ _PyType_GetSlotNames(PyTypeObject *cls)
/* Get the slot names from the cache in the class if possible. */ /* Get the slot names from the cache in the class if possible. */
PyObject *dict = lookup_tp_dict(cls); PyObject *dict = lookup_tp_dict(cls);
slotnames = PyDict_GetItemWithError(dict, &_Py_ID(__slotnames__)); if (PyDict_GetItemRef(dict, &_Py_ID(__slotnames__), &slotnames) < 0) {
return NULL;
}
if (slotnames != NULL) { if (slotnames != NULL) {
if (slotnames != Py_None && !PyList_Check(slotnames)) { if (slotnames != Py_None && !PyList_Check(slotnames)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%.200s.__slotnames__ should be a list or None, " "%.200s.__slotnames__ should be a list or None, "
"not %.200s", "not %.200s",
cls->tp_name, Py_TYPE(slotnames)->tp_name); cls->tp_name, Py_TYPE(slotnames)->tp_name);
Py_DECREF(slotnames);
return NULL; return NULL;
} }
return Py_NewRef(slotnames); return slotnames;
}
else {
if (PyErr_Occurred()) {
return NULL;
}
/* The class does not have the slot names cached yet. */
} }
/* The class does not have the slot names cached yet. */
copyreg = import_copyreg(); copyreg = import_copyreg();
if (copyreg == NULL) if (copyreg == NULL)
return NULL; return NULL;
@ -10264,23 +10243,18 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *
return NULL; return NULL;
/* keep a strong reference to mro because su_obj_type->tp_mro can be /* keep a strong reference to mro because su_obj_type->tp_mro can be
replaced during PyDict_GetItemWithError(dict, name) */ replaced during PyDict_GetItemRef(dict, name, &res) */
Py_INCREF(mro); Py_INCREF(mro);
do { do {
PyObject *obj = PyTuple_GET_ITEM(mro, i); PyObject *obj = PyTuple_GET_ITEM(mro, i);
PyObject *dict = lookup_tp_dict(_PyType_CAST(obj)); PyObject *dict = lookup_tp_dict(_PyType_CAST(obj));
assert(dict != NULL && PyDict_Check(dict)); assert(dict != NULL && PyDict_Check(dict));
res = PyDict_GetItemWithError(dict, name); if (PyDict_GetItemRef(dict, name, &res) != 0) {
if (res != NULL) { // found or error
Py_INCREF(res);
Py_DECREF(mro); Py_DECREF(mro);
return res; return res;
} }
else if (PyErr_Occurred()) {
Py_DECREF(mro);
return NULL;
}
i++; i++;
} while (i < n); } while (i < n);