mirror of https://github.com/python/cpython
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 .
This commit is contained in:
parent
1707e4020f
commit
60c3d3551a
|
@ -2183,16 +2183,25 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
|
||||||
PyObject *arg = NULL;
|
PyObject *arg = NULL;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg))
|
if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
|
||||||
result = -1;
|
result = -1;
|
||||||
|
}
|
||||||
else if (arg != NULL) {
|
else if (arg != NULL) {
|
||||||
_Py_IDENTIFIER(keys);
|
_Py_IDENTIFIER(keys);
|
||||||
if (_PyObject_HasAttrId(arg, &PyId_keys))
|
PyObject *func = _PyObject_GetAttrId(arg, &PyId_keys);
|
||||||
|
if (func != NULL) {
|
||||||
|
Py_DECREF(func);
|
||||||
result = PyDict_Merge(self, arg, 1);
|
result = PyDict_Merge(self, arg, 1);
|
||||||
else
|
}
|
||||||
|
else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
PyErr_Clear();
|
||||||
result = PyDict_MergeFromSeq2(self, arg, 1);
|
result = PyDict_MergeFromSeq2(self, arg, 1);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result == 0 && kwds != NULL) {
|
if (result == 0 && kwds != NULL) {
|
||||||
if (PyArg_ValidateKeywordArguments(kwds))
|
if (PyArg_ValidateKeywordArguments(kwds))
|
||||||
result = PyDict_Merge(self, kwds, 1);
|
result = PyDict_Merge(self, kwds, 1);
|
||||||
|
|
|
@ -2343,15 +2343,12 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
|
PyObject *func;
|
||||||
PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
|
PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
|
||||||
assert(other != NULL);
|
assert(other != NULL);
|
||||||
Py_INCREF(other);
|
Py_INCREF(other);
|
||||||
if PyDict_CheckExact(other) {
|
if (PyDict_CheckExact(other)) {
|
||||||
PyObject *items;
|
PyObject *items = PyDict_Items(other);
|
||||||
if (PyDict_CheckExact(other))
|
|
||||||
items = PyDict_Items(other);
|
|
||||||
else
|
|
||||||
items = _PyObject_CallMethodId(other, &PyId_items, NULL);
|
|
||||||
Py_DECREF(other);
|
Py_DECREF(other);
|
||||||
if (items == NULL)
|
if (items == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2359,10 +2356,14 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_DECREF(items);
|
Py_DECREF(items);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
goto handle_kwargs;
|
||||||
}
|
}
|
||||||
else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */
|
|
||||||
|
func = _PyObject_GetAttrId(other, &PyId_keys);
|
||||||
|
if (func != NULL) {
|
||||||
PyObject *keys, *iterator, *key;
|
PyObject *keys, *iterator, *key;
|
||||||
keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
|
keys = _PyObject_CallNoArg(func);
|
||||||
|
Py_DECREF(func);
|
||||||
if (keys == NULL) {
|
if (keys == NULL) {
|
||||||
Py_DECREF(other);
|
Py_DECREF(other);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2388,29 +2389,45 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_DECREF(iterator);
|
Py_DECREF(iterator);
|
||||||
if (res != 0 || PyErr_Occurred())
|
if (res != 0 || PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
goto handle_kwargs;
|
||||||
}
|
}
|
||||||
else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
|
else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
PyObject *items;
|
|
||||||
if (PyDict_CheckExact(other))
|
|
||||||
items = PyDict_Items(other);
|
|
||||||
else
|
|
||||||
items = _PyObject_CallMethodId(other, &PyId_items, NULL);
|
|
||||||
Py_DECREF(other);
|
Py_DECREF(other);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
func = _PyObject_GetAttrId(other, &PyId_items);
|
||||||
|
if (func != NULL) {
|
||||||
|
PyObject *items;
|
||||||
|
Py_DECREF(other);
|
||||||
|
items = _PyObject_CallNoArg(func);
|
||||||
|
Py_DECREF(func);
|
||||||
if (items == NULL)
|
if (items == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
res = mutablemapping_add_pairs(self, items);
|
res = mutablemapping_add_pairs(self, items);
|
||||||
Py_DECREF(items);
|
Py_DECREF(items);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
goto handle_kwargs;
|
||||||
|
}
|
||||||
|
else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
Py_DECREF(other);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
res = mutablemapping_add_pairs(self, other);
|
res = mutablemapping_add_pairs(self, other);
|
||||||
Py_DECREF(other);
|
Py_DECREF(other);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
handle_kwargs:
|
||||||
/* now handle kwargs */
|
/* now handle kwargs */
|
||||||
assert(kwargs == NULL || PyDict_Check(kwargs));
|
assert(kwargs == NULL || PyDict_Check(kwargs));
|
||||||
if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
|
if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
|
||||||
|
|
Loading…
Reference in New Issue