Mercurial > cpython-lru_cache-weakref
annotate Lib/test/test_iterlen.py @ 79675:c0a2294de787 2.7
Issue #16199: Backport 2to3 typo fix from 3.2.
| author | Chris Jerdonek <chris.jerdonek@gmail.com> |
|---|---|
| date | Thu, 11 Oct 2012 16:15:46 -0700 |
| parents | cd8d3c2d3bce |
| children |
| rev | line source |
|---|---|
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
1 """ Test Iterator Length Transparency |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
2 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
3 Some functions or methods which accept general iterable arguments have |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
4 optional, more efficient code paths if they know how many items to expect. |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
5 For instance, map(func, iterable), will pre-allocate the exact amount of |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
6 space required whenever the iterable can report its length. |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
7 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
8 The desired invariant is: len(it)==len(list(it)). |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
9 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
10 A complication is that an iterable and iterator can be the same object. To |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
11 maintain the invariant, an iterator needs to dynamically update its length. |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
12 For instance, an iterable such as xrange(10) always reports its length as ten, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
13 but it=iter(xrange(10)) starts at ten, and then goes to nine after it.next(). |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
14 Having this capability means that map() can ignore the distinction between |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
15 map(func, iterable) and map(func, iter(iterable)). |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
16 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
17 When the iterable is immutable, the implementation can straight-forwardly |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
18 report the original length minus the cumulative number of calls to next(). |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
19 This is the case for tuples, xrange objects, and itertools.repeat(). |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
20 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
21 Some containers become temporarily immutable during iteration. This includes |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
22 dicts, sets, and collections.deque. Their implementation is equally simple |
|
68588
cd8d3c2d3bce
#11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
51289
diff
changeset
|
23 though they need to permanently set their length to zero whenever there is |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
24 an attempt to iterate after a length mutation. |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
25 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
26 The situation slightly more involved whenever an object allows length mutation |
|
68588
cd8d3c2d3bce
#11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
51289
diff
changeset
|
27 during iteration. Lists and sequence iterators are dynamically updatable. |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
28 So, if a list is extended during iteration, the iterator will continue through |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
29 the new items. If it shrinks to a point before the most recent iteration, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
30 then no further items are available and the length is reported at zero. |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
31 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
32 Reversed objects can also be wrapped around mutable objects; however, any |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
33 appends after the current position are ignored. Any other approach leads |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
34 to confusion and possibly returning the same item more than once. |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
35 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
36 The iterators not listed above, such as enumerate and the other itertools, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
37 are not length transparent because they have no way to distinguish between |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
38 iterables that report static length and iterators whose length changes with |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
39 each call (i.e. the difference between enumerate('abc') and |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
40 enumerate(iter('abc')). |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
41 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
42 """ |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
43 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
44 import unittest |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
45 from test import test_support |
|
35636
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
46 from itertools import repeat |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
47 from collections import deque |
|
35636
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
48 from __builtin__ import len as _len |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
49 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
50 n = 10 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
51 |
|
35636
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
52 def len(obj): |
|
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
53 try: |
|
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
54 return _len(obj) |
|
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
55 except TypeError: |
|
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
56 try: |
|
36484
20f75d5e79e9
Renamed _length_cue() to __length_hint__(). See:
Armin Rigo <arigo@tunes.org>
parents:
35636
diff
changeset
|
57 # note: this is an internal undocumented API, |
|
20f75d5e79e9
Renamed _length_cue() to __length_hint__(). See:
Armin Rigo <arigo@tunes.org>
parents:
35636
diff
changeset
|
58 # don't rely on it in your own programs |
|
20f75d5e79e9
Renamed _length_cue() to __length_hint__(). See:
Armin Rigo <arigo@tunes.org>
parents:
35636
diff
changeset
|
59 return obj.__length_hint__() |
|
35636
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
60 except AttributeError: |
|
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
61 raise TypeError |
|
e22334b1da67
Convert iterator __len__() methods to a private API.
Raymond Hettinger <python@rcn.com>
parents:
32538
diff
changeset
|
62 |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
63 class TestInvariantWithoutMutations(unittest.TestCase): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
64 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
65 def test_invariant(self): |
|
32538
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
66 it = self.it |
|
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
67 for i in reversed(xrange(1, n+1)): |
|
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
68 self.assertEqual(len(it), i) |
|
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
69 it.next() |
|
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
70 self.assertEqual(len(it), 0) |
|
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
71 self.assertRaises(StopIteration, it.next) |
|
4fab4a5cce2f
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
31908
diff
changeset
|
72 self.assertEqual(len(it), 0) |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
73 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
74 class TestTemporarilyImmutable(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
75 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
76 def test_immutable_during_iteration(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
77 # objects such as deques, sets, and dictionaries enforce |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
78 # length immutability during iteration |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
79 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
80 it = self.it |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
81 self.assertEqual(len(it), n) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
82 it.next() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
83 self.assertEqual(len(it), n-1) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
84 self.mutate() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
85 self.assertRaises(RuntimeError, it.next) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
86 self.assertEqual(len(it), 0) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
87 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
88 ## ------- Concrete Type Tests ------- |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
89 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
90 class TestRepeat(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
91 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
92 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
93 self.it = repeat(None, n) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
94 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
95 def test_no_len_for_infinite_repeat(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
96 # The repeat() object can also be infinite |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
97 self.assertRaises(TypeError, len, repeat(None)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
98 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
99 class TestXrange(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
100 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
101 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
102 self.it = iter(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
103 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
104 class TestXrangeCustomReversed(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
105 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
106 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
107 self.it = reversed(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
108 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
109 class TestTuple(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
110 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
111 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
112 self.it = iter(tuple(xrange(n))) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
113 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
114 ## ------- Types that should not be mutated during iteration ------- |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
115 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
116 class TestDeque(TestTemporarilyImmutable): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
117 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
118 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
119 d = deque(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
120 self.it = iter(d) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
121 self.mutate = d.pop |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
122 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
123 class TestDequeReversed(TestTemporarilyImmutable): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
124 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
125 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
126 d = deque(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
127 self.it = reversed(d) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
128 self.mutate = d.pop |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
129 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
130 class TestDictKeys(TestTemporarilyImmutable): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
131 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
132 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
133 d = dict.fromkeys(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
134 self.it = iter(d) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
135 self.mutate = d.popitem |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
136 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
137 class TestDictItems(TestTemporarilyImmutable): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
138 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
139 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
140 d = dict.fromkeys(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
141 self.it = d.iteritems() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
142 self.mutate = d.popitem |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
143 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
144 class TestDictValues(TestTemporarilyImmutable): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
145 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
146 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
147 d = dict.fromkeys(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
148 self.it = d.itervalues() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
149 self.mutate = d.popitem |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
150 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
151 class TestSet(TestTemporarilyImmutable): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
152 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
153 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
154 d = set(xrange(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
155 self.it = iter(d) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
156 self.mutate = d.pop |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
157 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
158 ## ------- Types that can mutate during iteration ------- |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
159 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
160 class TestList(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
161 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
162 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
163 self.it = iter(range(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
164 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
165 def test_mutation(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
166 d = range(n) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
167 it = iter(d) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
168 it.next() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
169 it.next() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
170 self.assertEqual(len(it), n-2) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
171 d.append(n) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
172 self.assertEqual(len(it), n-1) # grow with append |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
173 d[1:] = [] |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
174 self.assertEqual(len(it), 0) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
175 self.assertEqual(list(it), []) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
176 d.extend(xrange(20)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
177 self.assertEqual(len(it), 0) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
178 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
179 class TestListReversed(TestInvariantWithoutMutations): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
180 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
181 def setUp(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
182 self.it = reversed(range(n)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
183 |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
184 def test_mutation(self): |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
185 d = range(n) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
186 it = reversed(d) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
187 it.next() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
188 it.next() |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
189 self.assertEqual(len(it), n-2) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
190 d.append(n) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
191 self.assertEqual(len(it), n-2) # ignore append |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
192 d[1:] = [] |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
193 self.assertEqual(len(it), 0) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
194 self.assertEqual(list(it), []) # confirm invariant |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
195 d.extend(xrange(20)) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
196 self.assertEqual(len(it), 0) |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
197 |
|
51282
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
198 ## -- Check to make sure exceptions are not suppressed by __length_hint__() |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
199 |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
200 |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
201 class BadLen(object): |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
202 def __iter__(self): return iter(range(10)) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
203 def __len__(self): |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
204 raise RuntimeError('hello') |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
205 |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
206 class BadLengthHint(object): |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
207 def __iter__(self): return iter(range(10)) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
208 def __length_hint__(self): |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
209 raise RuntimeError('hello') |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
210 |
|
51289
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
211 class NoneLengthHint(object): |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
212 def __iter__(self): return iter(range(10)) |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
213 def __length_hint__(self): |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
214 return None |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
215 |
|
51282
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
216 class TestLengthHintExceptions(unittest.TestCase): |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
217 |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
218 def test_issue1242657(self): |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
219 self.assertRaises(RuntimeError, list, BadLen()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
220 self.assertRaises(RuntimeError, list, BadLengthHint()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
221 self.assertRaises(RuntimeError, [].extend, BadLen()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
222 self.assertRaises(RuntimeError, [].extend, BadLengthHint()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
223 self.assertRaises(RuntimeError, zip, BadLen()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
224 self.assertRaises(RuntimeError, zip, BadLengthHint()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
225 self.assertRaises(RuntimeError, filter, None, BadLen()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
226 self.assertRaises(RuntimeError, filter, None, BadLengthHint()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
227 self.assertRaises(RuntimeError, map, chr, BadLen()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
228 self.assertRaises(RuntimeError, map, chr, BadLengthHint()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
229 b = bytearray(range(10)) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
230 self.assertRaises(RuntimeError, b.extend, BadLen()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
231 self.assertRaises(RuntimeError, b.extend, BadLengthHint()) |
|
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
232 |
|
51289
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
233 def test_invalid_hint(self): |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
234 # Make sure an invalid result doesn't muck-up the works |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
235 self.assertEqual(list(NoneLengthHint()), list(range(10))) |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
236 |
|
3880a1592137
Validate that __length_hint__ returns a usable result.
Raymond Hettinger <python@rcn.com>
parents:
51282
diff
changeset
|
237 |
|
39206
025c27b812f6
Add test_main() methods. These three tests were never run
Georg Brandl <georg@python.org>
parents:
36484
diff
changeset
|
238 def test_main(): |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
239 unittests = [ |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
240 TestRepeat, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
241 TestXrange, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
242 TestXrangeCustomReversed, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
243 TestTuple, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
244 TestDeque, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
245 TestDequeReversed, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
246 TestDictKeys, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
247 TestDictItems, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
248 TestDictValues, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
249 TestSet, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
250 TestList, |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
251 TestListReversed, |
|
51282
ca71a44d5432
Issue 1242657: list(obj) can swallow KeyboardInterrupt
Raymond Hettinger <python@rcn.com>
parents:
45212
diff
changeset
|
252 TestLengthHintExceptions, |
|
31908
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
253 ] |
|
058821d8aefd
* Add unittests for iterators that report their length
Raymond Hettinger <python@rcn.com>
parents:
diff
changeset
|
254 test_support.run_unittest(*unittests) |
|
39206
025c27b812f6
Add test_main() methods. These three tests were never run
Georg Brandl <georg@python.org>
parents:
36484
diff
changeset
|
255 |
|
025c27b812f6
Add test_main() methods. These three tests were never run
Georg Brandl <georg@python.org>
parents:
36484
diff
changeset
|
256 if __name__ == "__main__": |
|
025c27b812f6
Add test_main() methods. These three tests were never run
Georg Brandl <georg@python.org>
parents:
36484
diff
changeset
|
257 test_main() |
