From: Raymond Hettinger Date: Thu, 24 Apr 2003 16:52:47 +0000 (+0000) Subject: SF bug 665835: filter() treatment of str and tuple inconsistent X-Git-Tag: v2.3c1~1028 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9928571f3f09ece9430c4eb503ac7e9188d1b185;p=thirdparty%2FPython%2Fcpython.git SF bug 665835: filter() treatment of str and tuple inconsistent As a side issue on this bug, it was noted that list and tuple iterators used macros to directly access containers and would not recognize __getitem__ overrides. If the method is overridden, the patch returns a generic sequence iterator which calls the __getitem__ method; otherwise, it returns a high custom iterator with direct access to container elements. --- diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 4adbb406c68c..7e238df3e0ae 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -256,6 +256,12 @@ def f(): yield i vereq(list(tuple(f())), range(1000)) +# Verify that __getitem__ overrides are recognized by __iter__ +class T(tuple): + def __getitem__(self, key): + return str(key) + '!!!' +vereq(iter(T()).next(), '0!!!') + print '6.5.3 Lists' # calling built-in types without argument must return empty if list() != []: raise TestFailed,'list() does not return []' @@ -447,6 +453,12 @@ a = range(10) a[::2] = tuple(range(5)) vereq(a, [0, 1, 1, 3, 2, 5, 3, 7, 4, 9]) +# Verify that __getitem__ overrides are recognized by __iter__ +class L(list): + def __getitem__(self, key): + return str(key) + '!!!' +vereq(iter(L()).next(), '0!!!') + print '6.6 Mappings == Dictionaries' # calling built-in types without argument must return empty diff --git a/Objects/listobject.c b/Objects/listobject.c index 047c6ec98900..ae2b5493f8a5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2375,6 +2375,8 @@ list_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } + if (seq->ob_type->tp_as_sequence->sq_item != list_item) + return PySeqIter_New(seq); it = PyObject_GC_New(listiterobject, &PyListIter_Type); if (it == NULL) return NULL; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 282da3e8b97b..645480c9552e 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -753,6 +753,8 @@ tuple_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } + if (seq->ob_type->tp_as_sequence->sq_item != tupleitem) + return PySeqIter_New(seq); it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type); if (it == NULL) return NULL;