summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_iter.py
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-05-05 10:06:17 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-05-05 10:06:17 (GMT)
commitde9725f1352856b7d6de1bb29383a7be5f181740 (patch)
tree3fff3245c5dff4684440f7e9227c34bed9ef27b5 /Lib/test/test_iter.py
parent2cfe36828342e16cd274b968736a01aed5c49557 (diff)
downloadcpython-de9725f1352856b7d6de1bb29383a7be5f181740.zip
cpython-de9725f1352856b7d6de1bb29383a7be5f181740.tar.gz
cpython-de9725f1352856b7d6de1bb29383a7be5f181740.tar.bz2
Make 'x in y' and 'x not in y' (PySequence_Contains) play nice w/ iterators.
NEEDS DOC CHANGES A few more AttributeErrors turned into TypeErrors, but in test_contains this time. The full story for instance objects is pretty much unexplainable, because instance_contains() tries its own flavor of iteration-based containment testing first, and PySequence_Contains doesn't get a chance at it unless instance_contains() blows up. A consequence is that some_complex_number in some_instance dies with a TypeError unless some_instance.__class__ defines __iter__ but does not define __getitem__.
Diffstat (limited to 'Lib/test/test_iter.py')
-rw-r--r--Lib/test/test_iter.py55
1 files changed, 55 insertions, 0 deletions
diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py
index 073ffb4..bb9b102 100644
--- a/Lib/test/test_iter.py
+++ b/Lib/test/test_iter.py
@@ -472,4 +472,59 @@ class TestCase(unittest.TestCase):
except OSError:
pass
+ # Test iterators with 'x in y' and 'x not in y'.
+ def test_in_and_not_in(self):
+ sc5 = IteratingSequenceClass(5)
+ for i in range(5):
+ self.assert_(i in sc5)
+ # CAUTION: This test fails on 3-12j if sc5 is SequenceClass(5)
+ # instead, with:
+ # TypeError: cannot compare complex numbers using <, <=, >, >=
+ # The trail leads back to instance_contains() in classobject.c,
+ # under comment:
+ # /* fall back to previous behavior */
+ # IteratingSequenceClass(5) avoids the same problem only because
+ # it lacks __getitem__: instance_contains *tries* to do a wrong
+ # thing with it too, but aborts with an AttributeError the first
+ # time it calls instance_item(); PySequence_Contains() then catches
+ # that and clears it, and tries the iterator-based "contains"
+ # instead. But this is hanging together by a thread.
+ for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
+ self.assert_(i not in sc5)
+ del sc5
+
+ self.assertRaises(TypeError, lambda: 3 in 12)
+ self.assertRaises(TypeError, lambda: 3 not in map)
+
+ d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
+ for k in d:
+ self.assert_(k in d)
+ self.assert_(k not in d.itervalues())
+ for v in d.values():
+ self.assert_(v in d.itervalues())
+ self.assert_(v not in d)
+ for k, v in d.iteritems():
+ self.assert_((k, v) in d.iteritems())
+ self.assert_((v, k) not in d.iteritems())
+ del d
+
+ f = open(TESTFN, "w")
+ try:
+ f.write("a\n" "b\n" "c\n")
+ finally:
+ f.close()
+ f = open(TESTFN, "r")
+ try:
+ for chunk in "abc":
+ f.seek(0, 0)
+ self.assert_(chunk not in f)
+ f.seek(0, 0)
+ self.assert_((chunk + "\n") in f)
+ finally:
+ f.close()
+ try:
+ unlink(TESTFN)
+ except OSError:
+ pass
+
run_unittest(TestCase)