From 8c3e5e68ec2358660abbcce34b7c40be385618e1 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 24 Sep 2017 21:01:36 +0300 Subject: [PATCH 1/2] bpo-31572: Get rid of _PyObject_HasAttrId() in dict and OrderedDict. --- Objects/dictobject.c | 17 +++++++++++---- Objects/odictobject.c | 48 +++++++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 6ba2cc975fcb7e..e7eb179451aa2e 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 afacb36f6b3b55..29e45e482eea8f 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -2343,15 +2343,13 @@ 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); + items = PyDict_Items(other); Py_DECREF(other); if (items == NULL) return NULL; @@ -2359,10 +2357,14 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) Py_DECREF(items); if (res == -1) return NULL; + goto handge_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 +2390,45 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) Py_DECREF(iterator); if (res != 0 || PyErr_Occurred()) return NULL; + goto handge_kwargs; + } + else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + Py_DECREF(other); + return NULL; } - else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */ + else { + PyErr_Clear(); + } + + 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 handge_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; } +handge_kwargs: /* now handle kwargs */ assert(kwargs == NULL || PyDict_Check(kwargs)); if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) { From 5ad2ea14ce0425714a0093776eec19b9d8ffeed8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 11 Nov 2017 15:36:30 +0200 Subject: [PATCH 2/2] Fix typos. --- Objects/odictobject.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 9f43bcde7cd4d2..218aa2c5d9ce03 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -2347,9 +2347,8 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */ assert(other != NULL); Py_INCREF(other); - if PyDict_CheckExact(other) { - PyObject *items; - items = PyDict_Items(other); + if (PyDict_CheckExact(other)) { + PyObject *items = PyDict_Items(other); Py_DECREF(other); if (items == NULL) return NULL; @@ -2357,7 +2356,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) Py_DECREF(items); if (res == -1) return NULL; - goto handge_kwargs; + goto handle_kwargs; } func = _PyObject_GetAttrId(other, &PyId_keys); @@ -2390,7 +2389,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) Py_DECREF(iterator); if (res != 0 || PyErr_Occurred()) return NULL; - goto handge_kwargs; + goto handle_kwargs; } else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { Py_DECREF(other); @@ -2412,7 +2411,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) Py_DECREF(items); if (res == -1) return NULL; - goto handge_kwargs; + goto handle_kwargs; } else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { Py_DECREF(other); @@ -2428,7 +2427,7 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } -handge_kwargs: + handle_kwargs: /* now handle kwargs */ assert(kwargs == NULL || PyDict_Check(kwargs)); if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {