summaryrefslogtreecommitdiff
path: root/Objects/odictobject.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-11-11 16:19:56 +0200
committerGitHub <noreply@github.com>2017-11-11 16:19:56 +0200
commit60c3d3551a96febac7b6016fb44605643842c686 (patch)
tree5c676b97f4ef58958a3042d143eddb38325b7008 /Objects/odictobject.c
parent1707e4020fa8dca8e6a3ac4f9da105b54d597b66 (diff)
downloadcpython-git-60c3d3551a96febac7b6016fb44605643842c686.tar.gz
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 .
Diffstat (limited to 'Objects/odictobject.c')
-rw-r--r--Objects/odictobject.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index 5d22ce7158..218aa2c5d9 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -2343,15 +2343,12 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
}
if (len) {
+ PyObject *func;
PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
assert(other != NULL);
Py_INCREF(other);
- if PyDict_CheckExact(other) {
- PyObject *items;
- if (PyDict_CheckExact(other))
- items = PyDict_Items(other);
- else
- items = _PyObject_CallMethodId(other, &PyId_items, NULL);
+ if (PyDict_CheckExact(other)) {
+ PyObject *items = PyDict_Items(other);
Py_DECREF(other);
if (items == NULL)
return NULL;
@@ -2359,10 +2356,14 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
Py_DECREF(items);
if (res == -1)
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;
- keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
+ keys = _PyObject_CallNoArg(func);
+ Py_DECREF(func);
if (keys == NULL) {
Py_DECREF(other);
return NULL;
@@ -2388,29 +2389,45 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
Py_DECREF(iterator);
if (res != 0 || PyErr_Occurred())
return NULL;
+ goto handle_kwargs;
+ }
+ else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ Py_DECREF(other);
+ return NULL;
+ }
+ else {
+ PyErr_Clear();
}
- else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
+
+ func = _PyObject_GetAttrId(other, &PyId_items);
+ if (func != NULL) {
PyObject *items;
- if (PyDict_CheckExact(other))
- items = PyDict_Items(other);
- else
- items = _PyObject_CallMethodId(other, &PyId_items, NULL);
Py_DECREF(other);
+ items = _PyObject_CallNoArg(func);
+ Py_DECREF(func);
if (items == NULL)
return NULL;
res = mutablemapping_add_pairs(self, items);
Py_DECREF(items);
if (res == -1)
return NULL;
+ goto handle_kwargs;
}
- else {
- res = mutablemapping_add_pairs(self, other);
+ else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
Py_DECREF(other);
- if (res != 0)
- return NULL;
+ return NULL;
}
+ else {
+ PyErr_Clear();
+ }
+
+ res = mutablemapping_add_pairs(self, other);
+ Py_DECREF(other);
+ if (res != 0)
+ return NULL;
}
+ handle_kwargs:
/* now handle kwargs */
assert(kwargs == NULL || PyDict_Check(kwargs));
if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {