Skip to content

Commit 60c3d35

Browse files
bpo-31572: Get rid of _PyObject_HasAttrId() in dict and OrderedDict. (#3728)
Silence only AttributeError when get "key" and "items" attributes in the constructor and the update() method of dict and OrderedDict .
1 parent 1707e40 commit 60c3d35

File tree

2 files changed

+47
-21
lines changed

2 files changed

+47
-21
lines changed

Objects/dictobject.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,16 +2183,25 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
21832183
PyObject *arg = NULL;
21842184
int result = 0;
21852185

2186-
if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg))
2186+
if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
21872187
result = -1;
2188-
2188+
}
21892189
else if (arg != NULL) {
21902190
_Py_IDENTIFIER(keys);
2191-
if (_PyObject_HasAttrId(arg, &PyId_keys))
2191+
PyObject *func = _PyObject_GetAttrId(arg, &PyId_keys);
2192+
if (func != NULL) {
2193+
Py_DECREF(func);
21922194
result = PyDict_Merge(self, arg, 1);
2193-
else
2195+
}
2196+
else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2197+
PyErr_Clear();
21942198
result = PyDict_MergeFromSeq2(self, arg, 1);
2199+
}
2200+
else {
2201+
result = -1;
2202+
}
21952203
}
2204+
21962205
if (result == 0 && kwds != NULL) {
21972206
if (PyArg_ValidateKeywordArguments(kwds))
21982207
result = PyDict_Merge(self, kwds, 1);

Objects/odictobject.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,26 +2343,27 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
23432343
}
23442344

23452345
if (len) {
2346+
PyObject *func;
23462347
PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
23472348
assert(other != NULL);
23482349
Py_INCREF(other);
2349-
if PyDict_CheckExact(other) {
2350-
PyObject *items;
2351-
if (PyDict_CheckExact(other))
2352-
items = PyDict_Items(other);
2353-
else
2354-
items = _PyObject_CallMethodId(other, &PyId_items, NULL);
2350+
if (PyDict_CheckExact(other)) {
2351+
PyObject *items = PyDict_Items(other);
23552352
Py_DECREF(other);
23562353
if (items == NULL)
23572354
return NULL;
23582355
res = mutablemapping_add_pairs(self, items);
23592356
Py_DECREF(items);
23602357
if (res == -1)
23612358
return NULL;
2359+
goto handle_kwargs;
23622360
}
2363-
else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */
2361+
2362+
func = _PyObject_GetAttrId(other, &PyId_keys);
2363+
if (func != NULL) {
23642364
PyObject *keys, *iterator, *key;
2365-
keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
2365+
keys = _PyObject_CallNoArg(func);
2366+
Py_DECREF(func);
23662367
if (keys == NULL) {
23672368
Py_DECREF(other);
23682369
return NULL;
@@ -2388,29 +2389,45 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
23882389
Py_DECREF(iterator);
23892390
if (res != 0 || PyErr_Occurred())
23902391
return NULL;
2392+
goto handle_kwargs;
2393+
}
2394+
else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
2395+
Py_DECREF(other);
2396+
return NULL;
2397+
}
2398+
else {
2399+
PyErr_Clear();
23912400
}
2392-
else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
2401+
2402+
func = _PyObject_GetAttrId(other, &PyId_items);
2403+
if (func != NULL) {
23932404
PyObject *items;
2394-
if (PyDict_CheckExact(other))
2395-
items = PyDict_Items(other);
2396-
else
2397-
items = _PyObject_CallMethodId(other, &PyId_items, NULL);
23982405
Py_DECREF(other);
2406+
items = _PyObject_CallNoArg(func);
2407+
Py_DECREF(func);
23992408
if (items == NULL)
24002409
return NULL;
24012410
res = mutablemapping_add_pairs(self, items);
24022411
Py_DECREF(items);
24032412
if (res == -1)
24042413
return NULL;
2414+
goto handle_kwargs;
24052415
}
2406-
else {
2407-
res = mutablemapping_add_pairs(self, other);
2416+
else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
24082417
Py_DECREF(other);
2409-
if (res != 0)
2410-
return NULL;
2418+
return NULL;
24112419
}
2420+
else {
2421+
PyErr_Clear();
2422+
}
2423+
2424+
res = mutablemapping_add_pairs(self, other);
2425+
Py_DECREF(other);
2426+
if (res != 0)
2427+
return NULL;
24122428
}
24132429

2430+
handle_kwargs:
24142431
/* now handle kwargs */
24152432
assert(kwargs == NULL || PyDict_Check(kwargs));
24162433
if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {

0 commit comments

Comments
 (0)