From 793f75eeff0a7d9781074d152d84abcf73f4e2a2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 24 Sep 2017 20:52:03 +0300 Subject: [PATCH] bpo-31572: Get rid of using _PyObject_HasAttrId() in itertools. --- Modules/itertoolsmodule.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 2ac5ab24ec8abf..8becf317b5fc30 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -814,7 +814,7 @@ static PyObject * tee(PyObject *self, PyObject *args) { Py_ssize_t i, n=2; - PyObject *it, *iterable, *copyable, *result; + PyObject *it, *iterable, *copyable, *copyfunc, *result; _Py_IDENTIFIER(__copy__); if (!PyArg_ParseTuple(args, "O|n", &iterable, &n)) @@ -833,25 +833,43 @@ tee(PyObject *self, PyObject *args) Py_DECREF(result); return NULL; } - if (!_PyObject_HasAttrId(it, &PyId___copy__)) { + + copyfunc = _PyObject_GetAttrId(it, &PyId___copy__); + if (copyfunc != NULL) { + copyable = it; + } + else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + Py_DECREF(it); + Py_DECREF(result); + return NULL; + } + else { + PyErr_Clear(); copyable = tee_fromiterable(it); Py_DECREF(it); if (copyable == NULL) { Py_DECREF(result); return NULL; } - } else - copyable = it; - PyTuple_SET_ITEM(result, 0, copyable); - for (i=1 ; i