summaryrefslogtreecommitdiffstats
path: root/Modules/itertoolsmodule.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-11-11 13:51:42 (GMT)
committerGitHub <noreply@github.com>2017-11-11 13:51:42 (GMT)
commit1707e4020fa8dca8e6a3ac4f9da105b54d597b66 (patch)
treed536bf7f4a2a57cd9ba739f42f0c04a438af7a27 /Modules/itertoolsmodule.c
parentd4f8480dfe89447587550a85b61d4e9faf827e98 (diff)
downloadcpython-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.c32
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;
}