diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-11-11 14:19:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-11 14:19:56 (GMT) |
commit | 60c3d3551a96febac7b6016fb44605643842c686 (patch) | |
tree | 5c676b97f4ef58958a3042d143eddb38325b7008 /Objects | |
parent | 1707e4020fa8dca8e6a3ac4f9da105b54d597b66 (diff) | |
download | cpython-60c3d3551a96febac7b6016fb44605643842c686.zip cpython-60c3d3551a96febac7b6016fb44605643842c686.tar.gz cpython-60c3d3551a96febac7b6016fb44605643842c686.tar.bz2 |
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')
-rw-r--r-- | Objects/dictobject.c | 17 | ||||
-rw-r--r-- | Objects/odictobject.c | 51 |
2 files changed, 47 insertions, 21 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 779746a..b20b85c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2183,16 +2183,25 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, PyObject *arg = NULL; int result = 0; - if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) + if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) { result = -1; - + } else if (arg != NULL) { _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); - else + } + else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); result = PyDict_MergeFromSeq2(self, arg, 1); + } + else { + result = -1; + } } + if (result == 0 && kwds != NULL) { if (PyArg_ValidateKeywordArguments(kwds)) result = PyDict_Merge(self, kwds, 1); diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 5d22ce7..218aa2c 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)) { |