Skip to content

Commit 76725d7

Browse files
pythongh-111789: Use PyDict_GetItemRef() in Objects/
1 parent 178861b commit 76725d7

File tree

5 files changed

+73
-118
lines changed

5 files changed

+73
-118
lines changed

Objects/abstract.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,7 @@ int
204204
PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
205205
{
206206
if (PyDict_CheckExact(obj)) {
207-
*result = PyDict_GetItemWithError(obj, key); /* borrowed */
208-
if (*result) {
209-
Py_INCREF(*result);
210-
return 1;
211-
}
212-
return PyErr_Occurred() ? -1 : 0;
207+
return PyDict_GetItemRef(obj, key, result);
213208
}
214209

215210
*result = PyObject_GetItem(obj, key);

Objects/funcobject.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ PyFunction_ClearWatcher(int watcher_id)
9292
PyFunctionObject *
9393
_PyFunction_FromConstructor(PyFrameConstructor *constr)
9494
{
95-
PyObject *module = Py_XNewRef(PyDict_GetItemWithError(constr->fc_globals, &_Py_ID(__name__)));
96-
if (!module && PyErr_Occurred()) {
95+
PyObject *module;
96+
if (PyDict_GetItemRef(constr->fc_globals, &_Py_ID(__name__), &module) < 0) {
9797
return NULL;
9898
}
9999

@@ -158,12 +158,11 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
158158
Py_INCREF(doc);
159159

160160
// __module__: Use globals['__name__'] if it exists, or NULL.
161-
PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__));
161+
PyObject *module;
162162
PyObject *builtins = NULL;
163-
if (module == NULL && _PyErr_Occurred(tstate)) {
163+
if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &module) < 0) {
164164
goto error;
165165
}
166-
Py_XINCREF(module);
167166

168167
builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
169168
if (builtins == NULL) {

Objects/moduleobject.c

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ PyModule_GetNameObject(PyObject *mod)
522522
}
523523
PyObject *name;
524524
if (PyDict_GetItemRef(dict, &_Py_ID(__name__), &name) <= 0) {
525+
// error or not found
525526
goto error;
526527
}
527528
if (!PyUnicode_Check(name)) {
@@ -562,6 +563,7 @@ PyModule_GetFilenameObject(PyObject *mod)
562563
}
563564
PyObject *fileobj;
564565
if (PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj) <= 0) {
566+
// error or not found
565567
goto error;
566568
}
567569
if (!PyUnicode_Check(fileobj)) {
@@ -816,28 +818,28 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
816818
PyErr_Clear();
817819
}
818820
assert(m->md_dict != NULL);
819-
getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__));
821+
if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__getattr__), &getattr) < 0) {
822+
return NULL;
823+
}
820824
if (getattr) {
821825
PyObject *result = PyObject_CallOneArg(getattr, name);
822826
if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
823827
// suppress AttributeError
824828
PyErr_Clear();
825829
}
830+
Py_DECREF(getattr);
826831
return result;
827832
}
828-
if (PyErr_Occurred()) {
833+
if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__name__), &mod_name) < 0) {
829834
return NULL;
830835
}
831-
mod_name = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__name__));
832836
if (mod_name && PyUnicode_Check(mod_name)) {
833-
Py_INCREF(mod_name);
834-
PyObject *spec = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__spec__));
835-
if (spec == NULL && PyErr_Occurred()) {
837+
PyObject *spec;
838+
if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__spec__), &spec) < 0) {
836839
Py_DECREF(mod_name);
837840
return NULL;
838841
}
839842
if (suppress != 1) {
840-
Py_XINCREF(spec);
841843
if (_PyModuleSpec_IsInitializing(spec)) {
842844
PyErr_Format(PyExc_AttributeError,
843845
"partially initialized "
@@ -856,14 +858,12 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
856858
"module '%U' has no attribute '%U'",
857859
mod_name, name);
858860
}
859-
Py_XDECREF(spec);
860861
}
862+
Py_XDECREF(spec);
861863
Py_DECREF(mod_name);
862864
return NULL;
863865
}
864-
else if (PyErr_Occurred()) {
865-
return NULL;
866-
}
866+
Py_XDECREF(mod_name);
867867
if (suppress != 1) {
868868
PyErr_Format(PyExc_AttributeError,
869869
"module has no attribute '%U'", name);
@@ -957,11 +957,8 @@ module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
957957
return NULL;
958958
}
959959

960-
PyObject *annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
961-
if (annotations) {
962-
Py_INCREF(annotations);
963-
}
964-
else if (!PyErr_Occurred()) {
960+
PyObject *annotations;
961+
if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) == 0) {
965962
annotations = PyDict_New();
966963
if (annotations) {
967964
int result = PyDict_SetItem(

Objects/object.c

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,19 +1488,14 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
14881488
}
14891489
if (dict != NULL) {
14901490
Py_INCREF(dict);
1491-
PyObject *attr = PyDict_GetItemWithError(dict, name);
1492-
if (attr != NULL) {
1493-
*method = Py_NewRef(attr);
1491+
if (PyDict_GetItemRef(dict, name, method) != 0) {
1492+
// error or found
14941493
Py_DECREF(dict);
14951494
Py_XDECREF(descr);
14961495
return 0;
14971496
}
1497+
// not found
14981498
Py_DECREF(dict);
1499-
1500-
if (PyErr_Occurred()) {
1501-
Py_XDECREF(descr);
1502-
return 0;
1503-
}
15041499
}
15051500

15061501
if (meth_found) {
@@ -1606,20 +1601,17 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name,
16061601
if (dict != NULL) {
16071602
Py_INCREF(dict);
16081603
res = PyDict_GetItemWithError(dict, name);
1604+
int rc = PyDict_GetItemRef(dict, name, &res);
1605+
Py_DECREF(dict);
16091606
if (res != NULL) {
1610-
Py_INCREF(res);
1611-
Py_DECREF(dict);
16121607
goto done;
16131608
}
1614-
else {
1615-
Py_DECREF(dict);
1616-
if (PyErr_Occurred()) {
1617-
if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) {
1618-
PyErr_Clear();
1619-
}
1620-
else {
1621-
goto done;
1622-
}
1609+
else if (rc < 0) {
1610+
if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) {
1611+
PyErr_Clear();
1612+
}
1613+
else {
1614+
goto done;
16231615
}
16241616
}
16251617
}

Objects/typeobject.c

Lines changed: 44 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,14 +1092,9 @@ type_module(PyTypeObject *type, void *context)
10921092

10931093
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
10941094
PyObject *dict = lookup_tp_dict(type);
1095-
mod = PyDict_GetItemWithError(dict, &_Py_ID(__module__));
1096-
if (mod == NULL) {
1097-
if (!PyErr_Occurred()) {
1098-
PyErr_Format(PyExc_AttributeError, "__module__");
1099-
}
1100-
return NULL;
1095+
if (PyDict_GetItemRef(dict, &_Py_ID(__module__), &mod) == 0) {
1096+
PyErr_Format(PyExc_AttributeError, "__module__");
11011097
}
1102-
Py_INCREF(mod);
11031098
}
11041099
else {
11051100
const char *s = strrchr(type->tp_name, '.');
@@ -1134,17 +1129,16 @@ type_abstractmethods(PyTypeObject *type, void *context)
11341129
PyObject *mod = NULL;
11351130
/* type itself has an __abstractmethods__ descriptor (this). Don't return
11361131
that. */
1137-
if (type != &PyType_Type) {
1138-
PyObject *dict = lookup_tp_dict(type);
1139-
mod = PyDict_GetItemWithError(dict, &_Py_ID(__abstractmethods__));
1132+
if (type == &PyType_Type) {
1133+
PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__));
11401134
}
1141-
if (!mod) {
1142-
if (!PyErr_Occurred()) {
1135+
else {
1136+
PyObject *dict = lookup_tp_dict(type);
1137+
if (PyDict_GetItemRef(dict, &_Py_ID(__abstractmethods__), &mod) == 0) {
11431138
PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__));
11441139
}
1145-
return NULL;
11461140
}
1147-
return Py_NewRef(mod);
1141+
return mod;
11481142
}
11491143

11501144
static int
@@ -1435,18 +1429,12 @@ type_get_doc(PyTypeObject *type, void *context)
14351429
return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc);
14361430
}
14371431
PyObject *dict = lookup_tp_dict(type);
1438-
result = PyDict_GetItemWithError(dict, &_Py_ID(__doc__));
1439-
if (result == NULL) {
1440-
if (!PyErr_Occurred()) {
1441-
result = Py_NewRef(Py_None);
1442-
}
1443-
}
1444-
else if (Py_TYPE(result)->tp_descr_get) {
1445-
result = Py_TYPE(result)->tp_descr_get(result, NULL,
1446-
(PyObject *)type);
1432+
if (PyDict_GetItemRef(dict, &_Py_ID(__doc__), &result) == 0) {
1433+
result = Py_NewRef(Py_None);
14471434
}
1448-
else {
1449-
Py_INCREF(result);
1435+
else if (result && Py_TYPE(result)->tp_descr_get) {
1436+
Py_SETREF(result, Py_TYPE(result)->tp_descr_get(result, NULL,
1437+
(PyObject *)type));
14501438
}
14511439
return result;
14521440
}
@@ -1477,16 +1465,16 @@ type_get_annotations(PyTypeObject *type, void *context)
14771465

14781466
PyObject *annotations;
14791467
PyObject *dict = lookup_tp_dict(type);
1480-
annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
1468+
if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) < 0) {
1469+
return NULL;
1470+
}
14811471
if (annotations) {
14821472
if (Py_TYPE(annotations)->tp_descr_get) {
1483-
annotations = Py_TYPE(annotations)->tp_descr_get(
1484-
annotations, NULL, (PyObject *)type);
1485-
} else {
1486-
Py_INCREF(annotations);
1473+
Py_SETREF(annotations, Py_TYPE(annotations)->tp_descr_get(
1474+
annotations, NULL, (PyObject *)type));
14871475
}
14881476
}
1489-
else if (!PyErr_Occurred()) {
1477+
else {
14901478
annotations = PyDict_New();
14911479
if (annotations) {
14921480
int result = PyDict_SetItem(
@@ -1533,16 +1521,11 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
15331521
static PyObject *
15341522
type_get_type_params(PyTypeObject *type, void *context)
15351523
{
1536-
PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__));
1537-
1538-
if (params) {
1539-
return Py_NewRef(params);
1540-
}
1541-
if (PyErr_Occurred()) {
1542-
return NULL;
1524+
PyObject *params;
1525+
if (PyDict_GetItemRef(lookup_tp_dict(type), &_Py_ID(__type_params__), &params) == 0) {
1526+
params = PyTuple_New(0);
15431527
}
1544-
1545-
return PyTuple_New(0);
1528+
return params;
15461529
}
15471530

15481531
static int
@@ -3436,18 +3419,13 @@ type_new_set_module(PyTypeObject *type)
34363419
return 0;
34373420
}
34383421

3439-
PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__));
3440-
if (module == NULL) {
3441-
if (PyErr_Occurred()) {
3442-
return -1;
3443-
}
3444-
return 0;
3422+
PyObject *module;
3423+
r = PyDict_GetItemRef(globals, &_Py_ID(__name__), &module);
3424+
if (module) {
3425+
r = PyDict_SetItem(dict, &_Py_ID(__module__), module);
3426+
Py_DECREF(module);
34453427
}
3446-
3447-
if (PyDict_SetItem(dict, &_Py_ID(__module__), module) < 0) {
3448-
return -1;
3449-
}
3450-
return 0;
3428+
return r;
34513429
}
34523430

34533431

@@ -3458,23 +3436,24 @@ type_new_set_ht_name(PyTypeObject *type)
34583436
{
34593437
PyHeapTypeObject *et = (PyHeapTypeObject *)type;
34603438
PyObject *dict = lookup_tp_dict(type);
3461-
PyObject *qualname = PyDict_GetItemWithError(dict, &_Py_ID(__qualname__));
3439+
PyObject *qualname;
3440+
if (PyDict_GetItemRef(dict, &_Py_ID(__qualname__), &qualname) < 0) {
3441+
return -1;
3442+
}
34623443
if (qualname != NULL) {
34633444
if (!PyUnicode_Check(qualname)) {
34643445
PyErr_Format(PyExc_TypeError,
34653446
"type __qualname__ must be a str, not %s",
34663447
Py_TYPE(qualname)->tp_name);
3448+
Py_DECREF(qualname);
34673449
return -1;
34683450
}
3469-
et->ht_qualname = Py_NewRef(qualname);
3451+
et->ht_qualname = qualname;
34703452
if (PyDict_DelItem(dict, &_Py_ID(__qualname__)) < 0) {
34713453
return -1;
34723454
}
34733455
}
34743456
else {
3475-
if (PyErr_Occurred()) {
3476-
return -1;
3477-
}
34783457
et->ht_qualname = Py_NewRef(et->ht_name);
34793458
}
34803459
return 0;
@@ -5887,24 +5866,22 @@ _PyType_GetSlotNames(PyTypeObject *cls)
58875866

58885867
/* Get the slot names from the cache in the class if possible. */
58895868
PyObject *dict = lookup_tp_dict(cls);
5890-
slotnames = PyDict_GetItemWithError(dict, &_Py_ID(__slotnames__));
5869+
if (PyDict_GetItemRef(dict, &_Py_ID(__slotnames__), &slotnames) < 0) {
5870+
return NULL;
5871+
}
58915872
if (slotnames != NULL) {
58925873
if (slotnames != Py_None && !PyList_Check(slotnames)) {
58935874
PyErr_Format(PyExc_TypeError,
58945875
"%.200s.__slotnames__ should be a list or None, "
58955876
"not %.200s",
58965877
cls->tp_name, Py_TYPE(slotnames)->tp_name);
5878+
Py_DECREF(slotnames);
58975879
return NULL;
58985880
}
5899-
return Py_NewRef(slotnames);
5900-
}
5901-
else {
5902-
if (PyErr_Occurred()) {
5903-
return NULL;
5904-
}
5905-
/* The class does not have the slot names cached yet. */
5881+
return slotnames;
59065882
}
59075883

5884+
/* The class does not have the slot names cached yet. */
59085885
copyreg = import_copyreg();
59095886
if (copyreg == NULL)
59105887
return NULL;
@@ -10263,23 +10240,18 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *
1026310240
return NULL;
1026410241

1026510242
/* keep a strong reference to mro because su_obj_type->tp_mro can be
10266-
replaced during PyDict_GetItemWithError(dict, name) */
10243+
replaced during PyDict_GetItemRef(dict, name, &res) */
1026710244
Py_INCREF(mro);
1026810245
do {
1026910246
PyObject *obj = PyTuple_GET_ITEM(mro, i);
1027010247
PyObject *dict = lookup_tp_dict(_PyType_CAST(obj));
1027110248
assert(dict != NULL && PyDict_Check(dict));
1027210249

10273-
res = PyDict_GetItemWithError(dict, name);
10274-
if (res != NULL) {
10275-
Py_INCREF(res);
10250+
if (PyDict_GetItemRef(dict, name, &res) != 0) {
10251+
// error or found
1027610252
Py_DECREF(mro);
1027710253
return res;
1027810254
}
10279-
else if (PyErr_Occurred()) {
10280-
Py_DECREF(mro);
10281-
return NULL;
10282-
}
1028310255

1028410256
i++;
1028510257
} while (i < n);

0 commit comments

Comments
 (0)