summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2003-04-24 16:52:47 (GMT)
committerRaymond Hettinger <python@rcn.com>2003-04-24 16:52:47 (GMT)
commit9928571f3f09ece9430c4eb503ac7e9188d1b185 (patch)
tree2ebeef8113f1d705554fb74912aa3a4e67ebfb3c
parent3209410cb53457c0aa2facceb8d9a6ad24e1702d (diff)
downloadcpython-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.py12
-rw-r--r--Objects/listobject.c2
-rw-r--r--Objects/tupleobject.c2
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;