Skip to content

Commit b510e10

Browse files
bpo-42152: Use PyDict_Contains and PyDict_SetDefault if appropriate. (pythonGH-22986)
If PyDict_GetItemWithError is only used to check whether the key is in dict, it is better to use PyDict_Contains instead. And if it is used in combination with PyDict_SetItem, PyDict_SetDefault can replace the combination.
1 parent fb5db7e commit b510e10

File tree

11 files changed

+135
-163
lines changed

11 files changed

+135
-163
lines changed

Modules/_ctypes/_ctypes.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,10 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
492492
return NULL;
493493

494494
/* keep this for bw compatibility */
495-
if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_))
495+
int r = _PyDict_ContainsId(result->tp_dict, &PyId__abstract_);
496+
if (r > 0)
496497
return (PyObject *)result;
497-
if (PyErr_Occurred()) {
498+
if (r < 0) {
498499
Py_DECREF(result);
499500
return NULL;
500501
}
@@ -4397,15 +4398,13 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
43974398
}
43984399
val = PyTuple_GET_ITEM(args, i + index);
43994400
if (kwds) {
4400-
if (PyDict_GetItemWithError(kwds, name)) {
4401-
PyErr_Format(PyExc_TypeError,
4402-
"duplicate values for field %R",
4403-
name);
4404-
Py_DECREF(pair);
4405-
Py_DECREF(name);
4406-
return -1;
4407-
}
4408-
else if (PyErr_Occurred()) {
4401+
res = PyDict_Contains(kwds, name);
4402+
if (res != 0) {
4403+
if (res > 0) {
4404+
PyErr_Format(PyExc_TypeError,
4405+
"duplicate values for field %R",
4406+
name);
4407+
}
44094408
Py_DECREF(pair);
44104409
Py_DECREF(name);
44114410
return -1;

Modules/_ctypes/callbacks.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ TryAddRef(StgDictObject *dict, CDataObject *obj)
109109
IUnknown *punk;
110110
_Py_IDENTIFIER(_needs_com_addref_);
111111

112-
if (!_PyDict_GetItemIdWithError((PyObject *)dict, &PyId__needs_com_addref_)) {
113-
if (PyErr_Occurred()) {
112+
int r = _PyDict_ContainsId((PyObject *)dict, &PyId__needs_com_addref_);
113+
if (r <= 0) {
114+
if (r < 0) {
114115
PrintError("getting _needs_com_addref_");
115116
}
116117
return;

Modules/_pickle.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,26 +2004,21 @@ fast_save_enter(PicklerObject *self, PyObject *obj)
20042004
self->fast_nesting = -1;
20052005
return 0;
20062006
}
2007-
if (PyDict_GetItemWithError(self->fast_memo, key)) {
2008-
Py_DECREF(key);
2007+
int r = PyDict_Contains(self->fast_memo, key);
2008+
if (r > 0) {
20092009
PyErr_Format(PyExc_ValueError,
20102010
"fast mode: can't pickle cyclic objects "
20112011
"including object type %.200s at %p",
20122012
Py_TYPE(obj)->tp_name, obj);
2013-
self->fast_nesting = -1;
2014-
return 0;
20152013
}
2016-
if (PyErr_Occurred()) {
2017-
Py_DECREF(key);
2018-
self->fast_nesting = -1;
2019-
return 0;
2014+
else if (r == 0) {
2015+
r = PyDict_SetItem(self->fast_memo, key, Py_None);
20202016
}
2021-
if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
2022-
Py_DECREF(key);
2017+
Py_DECREF(key);
2018+
if (r != 0) {
20232019
self->fast_nesting = -1;
20242020
return 0;
20252021
}
2026-
Py_DECREF(key);
20272022
}
20282023
return 1;
20292024
}

Modules/posixmodule.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,13 +1526,11 @@ convertenviron(void)
15261526
Py_DECREF(d);
15271527
return NULL;
15281528
}
1529-
if (PyDict_GetItemWithError(d, k) == NULL) {
1530-
if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1531-
Py_DECREF(v);
1532-
Py_DECREF(k);
1533-
Py_DECREF(d);
1534-
return NULL;
1535-
}
1529+
if (PyDict_SetDefault(d, k, v) == NULL) {
1530+
Py_DECREF(v);
1531+
Py_DECREF(k);
1532+
Py_DECREF(d);
1533+
return NULL;
15361534
}
15371535
Py_DECREF(k);
15381536
Py_DECREF(v);

Modules/pyexpat.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,15 +1614,7 @@ static int init_handler_descrs(void)
16141614
if (descr == NULL)
16151615
return -1;
16161616

1617-
if (PyDict_GetItemWithError(Xmlparsetype.tp_dict, PyDescr_NAME(descr))) {
1618-
Py_DECREF(descr);
1619-
continue;
1620-
}
1621-
else if (PyErr_Occurred()) {
1622-
Py_DECREF(descr);
1623-
return -1;
1624-
}
1625-
if (PyDict_SetItem(Xmlparsetype.tp_dict, PyDescr_NAME(descr), descr) < 0) {
1617+
if (PyDict_SetDefault(Xmlparsetype.tp_dict, PyDescr_NAME(descr), descr) == NULL) {
16261618
Py_DECREF(descr);
16271619
return -1;
16281620
}

Modules/selectmodule.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,14 @@ select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
499499
key = PyLong_FromLong(fd);
500500
if (key == NULL)
501501
return NULL;
502-
if (PyDict_GetItemWithError(self->dict, key) == NULL) {
503-
if (!PyErr_Occurred()) {
504-
errno = ENOENT;
505-
PyErr_SetFromErrno(PyExc_OSError);
506-
}
502+
err = PyDict_Contains(self->dict, key);
503+
if (err < 0) {
504+
Py_DECREF(key);
505+
return NULL;
506+
}
507+
if (err == 0) {
508+
errno = ENOENT;
509+
PyErr_SetFromErrno(PyExc_OSError);
507510
Py_DECREF(key);
508511
return NULL;
509512
}

Objects/dictobject.c

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,8 +2544,8 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
25442544
goto Fail;
25452545
}
25462546
}
2547-
else if (PyDict_GetItemWithError(d, key) == NULL) {
2548-
if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) {
2547+
else {
2548+
if (PyDict_SetDefault(d, key, value) == NULL) {
25492549
Py_DECREF(key);
25502550
Py_DECREF(value);
25512551
goto Fail;
@@ -2660,19 +2660,20 @@ dict_merge(PyObject *a, PyObject *b, int override)
26602660
Py_INCREF(value);
26612661
if (override == 1)
26622662
err = insertdict(mp, key, hash, value);
2663-
else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) {
2664-
if (PyErr_Occurred()) {
2665-
Py_DECREF(value);
2666-
Py_DECREF(key);
2667-
return -1;
2663+
else {
2664+
err = _PyDict_Contains_KnownHash(a, key, hash);
2665+
if (err == 0) {
2666+
err = insertdict(mp, key, hash, value);
2667+
}
2668+
else if (err > 0) {
2669+
if (override != 0) {
2670+
_PyErr_SetKeyError(key);
2671+
Py_DECREF(value);
2672+
Py_DECREF(key);
2673+
return -1;
2674+
}
2675+
err = 0;
26682676
}
2669-
err = insertdict(mp, key, hash, value);
2670-
}
2671-
else if (override != 0) {
2672-
_PyErr_SetKeyError(key);
2673-
Py_DECREF(value);
2674-
Py_DECREF(key);
2675-
return -1;
26762677
}
26772678
Py_DECREF(value);
26782679
Py_DECREF(key);
@@ -2709,17 +2710,15 @@ dict_merge(PyObject *a, PyObject *b, int override)
27092710

27102711
for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
27112712
if (override != 1) {
2712-
if (PyDict_GetItemWithError(a, key) != NULL) {
2713-
if (override != 0) {
2713+
status = PyDict_Contains(a, key);
2714+
if (status != 0) {
2715+
if (status > 0) {
2716+
if (override == 0) {
2717+
Py_DECREF(key);
2718+
continue;
2719+
}
27142720
_PyErr_SetKeyError(key);
2715-
Py_DECREF(key);
2716-
Py_DECREF(iter);
2717-
return -1;
27182721
}
2719-
Py_DECREF(key);
2720-
continue;
2721-
}
2722-
else if (PyErr_Occurred()) {
27232722
Py_DECREF(key);
27242723
Py_DECREF(iter);
27252724
return -1;

0 commit comments

Comments
 (0)