diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-11-11 13:51:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-11 13:51:42 (GMT) |
commit | 1707e4020fa8dca8e6a3ac4f9da105b54d597b66 (patch) | |
tree | d536bf7f4a2a57cd9ba739f42f0c04a438af7a27 /Modules/itertoolsmodule.c | |
parent | d4f8480dfe89447587550a85b61d4e9faf827e98 (diff) | |
download | cpython-1707e4020fa8dca8e6a3ac4f9da105b54d597b66.zip cpython-1707e4020fa8dca8e6a3ac4f9da105b54d597b66.tar.gz cpython-1707e4020fa8dca8e6a3ac4f9da105b54d597b66.tar.bz2 |
bpo-31572: Silence only AttributeError when get the __copy__ attribute in itertools.tee(). (#3724)
Diffstat (limited to 'Modules/itertoolsmodule.c')
-rw-r--r-- | Modules/itertoolsmodule.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 9190236..985915f 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -810,7 +810,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)) @@ -829,25 +829,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<n ; i++) { + copyfunc = _PyObject_GetAttrId(copyable, &PyId___copy__); + if (copyfunc == NULL) { + Py_DECREF(copyable); + Py_DECREF(result); + return NULL; + } + } - copyable = _PyObject_CallMethodId(copyable, &PyId___copy__, NULL); + PyTuple_SET_ITEM(result, 0, copyable); + for (i = 1; i < n; i++) { + copyable = _PyObject_CallNoArg(copyfunc); if (copyable == NULL) { + Py_DECREF(copyfunc); Py_DECREF(result); return NULL; } PyTuple_SET_ITEM(result, i, copyable); } + Py_DECREF(copyfunc); return result; } |