diff options
author | Raymond Hettinger <python@rcn.com> | 2003-04-24 16:52:47 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2003-04-24 16:52:47 (GMT) |
commit | 9928571f3f09ece9430c4eb503ac7e9188d1b185 (patch) | |
tree | 2ebeef8113f1d705554fb74912aa3a4e67ebfb3c | |
parent | 3209410cb53457c0aa2facceb8d9a6ad24e1702d (diff) | |
download | cpython-9928571f3f09ece9430c4eb503ac7e9188d1b185.zip cpython-9928571f3f09ece9430c4eb503ac7e9188d1b185.tar.gz cpython-9928571f3f09ece9430c4eb503ac7e9188d1b185.tar.bz2 |
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.
-rw-r--r-- | Lib/test/test_types.py | 12 | ||||
-rw-r--r-- | Objects/listobject.c | 2 | ||||
-rw-r--r-- | Objects/tupleobject.c | 2 |
3 files changed, 16 insertions, 0 deletions
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 4adbb40..7e238df 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 047c6ec..ae2b549 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 282da3e..645480c 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; |