3 from test
import test_support
4 from UserList
import UserList
6 # We do a bit of trickery here to be able to test both the C implementation
7 # and the Python implementation of the module.
9 # Make it impossible to import the C implementation anymore.
10 sys
.modules
['_bisect'] = 0
11 # We must also handle the case that bisect was imported before.
12 if 'bisect' in sys
.modules
:
13 del sys
.modules
['bisect']
15 # Now we can import the module and get the pure Python implementation.
16 import bisect
as py_bisect
18 # Restore everything to normal.
19 del sys
.modules
['_bisect']
20 del sys
.modules
['bisect']
22 # This is now the module with the C implementation.
23 import bisect
as c_bisect
26 class TestBisect(unittest
.TestCase
):
30 self
.precomputedCases
= [
31 (self
.module
.bisect_right
, [], 1, 0),
32 (self
.module
.bisect_right
, [1], 0, 0),
33 (self
.module
.bisect_right
, [1], 1, 1),
34 (self
.module
.bisect_right
, [1], 2, 1),
35 (self
.module
.bisect_right
, [1, 1], 0, 0),
36 (self
.module
.bisect_right
, [1, 1], 1, 2),
37 (self
.module
.bisect_right
, [1, 1], 2, 2),
38 (self
.module
.bisect_right
, [1, 1, 1], 0, 0),
39 (self
.module
.bisect_right
, [1, 1, 1], 1, 3),
40 (self
.module
.bisect_right
, [1, 1, 1], 2, 3),
41 (self
.module
.bisect_right
, [1, 1, 1, 1], 0, 0),
42 (self
.module
.bisect_right
, [1, 1, 1, 1], 1, 4),
43 (self
.module
.bisect_right
, [1, 1, 1, 1], 2, 4),
44 (self
.module
.bisect_right
, [1, 2], 0, 0),
45 (self
.module
.bisect_right
, [1, 2], 1, 1),
46 (self
.module
.bisect_right
, [1, 2], 1.5, 1),
47 (self
.module
.bisect_right
, [1, 2], 2, 2),
48 (self
.module
.bisect_right
, [1, 2], 3, 2),
49 (self
.module
.bisect_right
, [1, 1, 2, 2], 0, 0),
50 (self
.module
.bisect_right
, [1, 1, 2, 2], 1, 2),
51 (self
.module
.bisect_right
, [1, 1, 2, 2], 1.5, 2),
52 (self
.module
.bisect_right
, [1, 1, 2, 2], 2, 4),
53 (self
.module
.bisect_right
, [1, 1, 2, 2], 3, 4),
54 (self
.module
.bisect_right
, [1, 2, 3], 0, 0),
55 (self
.module
.bisect_right
, [1, 2, 3], 1, 1),
56 (self
.module
.bisect_right
, [1, 2, 3], 1.5, 1),
57 (self
.module
.bisect_right
, [1, 2, 3], 2, 2),
58 (self
.module
.bisect_right
, [1, 2, 3], 2.5, 2),
59 (self
.module
.bisect_right
, [1, 2, 3], 3, 3),
60 (self
.module
.bisect_right
, [1, 2, 3], 4, 3),
61 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
62 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
63 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
64 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
65 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
66 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
67 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
68 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
69 (self
.module
.bisect_right
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
71 (self
.module
.bisect_left
, [], 1, 0),
72 (self
.module
.bisect_left
, [1], 0, 0),
73 (self
.module
.bisect_left
, [1], 1, 0),
74 (self
.module
.bisect_left
, [1], 2, 1),
75 (self
.module
.bisect_left
, [1, 1], 0, 0),
76 (self
.module
.bisect_left
, [1, 1], 1, 0),
77 (self
.module
.bisect_left
, [1, 1], 2, 2),
78 (self
.module
.bisect_left
, [1, 1, 1], 0, 0),
79 (self
.module
.bisect_left
, [1, 1, 1], 1, 0),
80 (self
.module
.bisect_left
, [1, 1, 1], 2, 3),
81 (self
.module
.bisect_left
, [1, 1, 1, 1], 0, 0),
82 (self
.module
.bisect_left
, [1, 1, 1, 1], 1, 0),
83 (self
.module
.bisect_left
, [1, 1, 1, 1], 2, 4),
84 (self
.module
.bisect_left
, [1, 2], 0, 0),
85 (self
.module
.bisect_left
, [1, 2], 1, 0),
86 (self
.module
.bisect_left
, [1, 2], 1.5, 1),
87 (self
.module
.bisect_left
, [1, 2], 2, 1),
88 (self
.module
.bisect_left
, [1, 2], 3, 2),
89 (self
.module
.bisect_left
, [1, 1, 2, 2], 0, 0),
90 (self
.module
.bisect_left
, [1, 1, 2, 2], 1, 0),
91 (self
.module
.bisect_left
, [1, 1, 2, 2], 1.5, 2),
92 (self
.module
.bisect_left
, [1, 1, 2, 2], 2, 2),
93 (self
.module
.bisect_left
, [1, 1, 2, 2], 3, 4),
94 (self
.module
.bisect_left
, [1, 2, 3], 0, 0),
95 (self
.module
.bisect_left
, [1, 2, 3], 1, 0),
96 (self
.module
.bisect_left
, [1, 2, 3], 1.5, 1),
97 (self
.module
.bisect_left
, [1, 2, 3], 2, 1),
98 (self
.module
.bisect_left
, [1, 2, 3], 2.5, 2),
99 (self
.module
.bisect_left
, [1, 2, 3], 3, 2),
100 (self
.module
.bisect_left
, [1, 2, 3], 4, 3),
101 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
102 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
103 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
104 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
105 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
106 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
107 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
108 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
109 (self
.module
.bisect_left
, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
112 def test_precomputed(self
):
113 for func
, data
, elem
, expected
in self
.precomputedCases
:
114 self
.assertEqual(func(data
, elem
), expected
)
115 self
.assertEqual(func(UserList(data
), elem
), expected
)
117 def test_negative_lo(self
):
120 self
.assertRaises(ValueError, mod
.bisect_left
, [1, 2, 3], 5, -1, 3),
121 self
.assertRaises(ValueError, mod
.bisect_right
, [1, 2, 3], 5, -1, 3),
122 self
.assertRaises(ValueError, mod
.insort_left
, [1, 2, 3], 5, -1, 3),
123 self
.assertRaises(ValueError, mod
.insort_right
, [1, 2, 3], 5, -1, 3),
125 def test_random(self
, n
=25):
126 from random
import randrange
128 data
= [randrange(0, n
, 2) for j
in xrange(i
)]
130 elem
= randrange(-1, n
+1)
131 ip
= self
.module
.bisect_left(data
, elem
)
133 self
.assertTrue(elem
<= data
[ip
])
135 self
.assertTrue(data
[ip
-1] < elem
)
136 ip
= self
.module
.bisect_right(data
, elem
)
138 self
.assertTrue(elem
< data
[ip
])
140 self
.assertTrue(data
[ip
-1] <= elem
)
142 def test_optionalSlicing(self
):
143 for func
, data
, elem
, expected
in self
.precomputedCases
:
145 lo
= min(len(data
), lo
)
146 for hi
in xrange(3,8):
147 hi
= min(len(data
), hi
)
148 ip
= func(data
, elem
, lo
, hi
)
149 self
.assertTrue(lo
<= ip
<= hi
)
150 if func
is self
.module
.bisect_left
and ip
< hi
:
151 self
.assertTrue(elem
<= data
[ip
])
152 if func
is self
.module
.bisect_left
and ip
> lo
:
153 self
.assertTrue(data
[ip
-1] < elem
)
154 if func
is self
.module
.bisect_right
and ip
< hi
:
155 self
.assertTrue(elem
< data
[ip
])
156 if func
is self
.module
.bisect_right
and ip
> lo
:
157 self
.assertTrue(data
[ip
-1] <= elem
)
158 self
.assertEqual(ip
, max(lo
, min(hi
, expected
)))
160 def test_backcompatibility(self
):
161 self
.assertEqual(self
.module
.bisect
, self
.module
.bisect_right
)
163 def test_keyword_args(self
):
164 data
= [10, 20, 30, 40, 50]
165 self
.assertEqual(self
.module
.bisect_left(a
=data
, x
=25, lo
=1, hi
=3), 2)
166 self
.assertEqual(self
.module
.bisect_right(a
=data
, x
=25, lo
=1, hi
=3), 2)
167 self
.assertEqual(self
.module
.bisect(a
=data
, x
=25, lo
=1, hi
=3), 2)
168 self
.module
.insort_left(a
=data
, x
=25, lo
=1, hi
=3)
169 self
.module
.insort_right(a
=data
, x
=25, lo
=1, hi
=3)
170 self
.module
.insort(a
=data
, x
=25, lo
=1, hi
=3)
171 self
.assertEqual(data
, [10, 20, 25, 25, 25, 30, 40, 50])
173 class TestBisectPython(TestBisect
):
176 class TestBisectC(TestBisect
):
179 #==============================================================================
181 class TestInsort(unittest
.TestCase
):
184 def test_vsBuiltinSort(self
, n
=500):
185 from random
import choice
186 for insorted
in (list(), UserList()):
188 digit
= choice("0123456789")
190 f
= self
.module
.insort_left
192 f
= self
.module
.insort_right
194 self
.assertEqual(sorted(insorted
), insorted
)
196 def test_backcompatibility(self
):
197 self
.assertEqual(self
.module
.insort
, self
.module
.insort_right
)
199 def test_listDerived(self
):
202 def insert(self
, index
, item
):
203 self
.data
.insert(index
, item
)
206 self
.module
.insort_left(lst
, 10)
207 self
.module
.insort_right(lst
, 5)
208 self
.assertEqual([5, 10], lst
.data
)
210 class TestInsortPython(TestInsort
):
213 class TestInsortC(TestInsort
):
216 #==============================================================================
220 "Dummy sequence class defining __len__ but not __getitem__."
225 "Dummy sequence class defining __getitem__ but not __len__."
226 def __getitem__(self
, ndx
):
230 "Dummy element that always raises an error during comparison"
231 def __cmp__(self
, other
):
232 raise ZeroDivisionError
234 class TestErrorHandling(unittest
.TestCase
):
237 def test_non_sequence(self
):
238 for f
in (self
.module
.bisect_left
, self
.module
.bisect_right
,
239 self
.module
.insort_left
, self
.module
.insort_right
):
240 self
.assertRaises(TypeError, f
, 10, 10)
242 def test_len_only(self
):
243 for f
in (self
.module
.bisect_left
, self
.module
.bisect_right
,
244 self
.module
.insort_left
, self
.module
.insort_right
):
245 self
.assertRaises(AttributeError, f
, LenOnly(), 10)
247 def test_get_only(self
):
248 for f
in (self
.module
.bisect_left
, self
.module
.bisect_right
,
249 self
.module
.insort_left
, self
.module
.insort_right
):
250 self
.assertRaises(AttributeError, f
, GetOnly(), 10)
252 def test_cmp_err(self
):
253 seq
= [CmpErr(), CmpErr(), CmpErr()]
254 for f
in (self
.module
.bisect_left
, self
.module
.bisect_right
,
255 self
.module
.insort_left
, self
.module
.insort_right
):
256 self
.assertRaises(ZeroDivisionError, f
, seq
, 10)
258 def test_arg_parsing(self
):
259 for f
in (self
.module
.bisect_left
, self
.module
.bisect_right
,
260 self
.module
.insort_left
, self
.module
.insort_right
):
261 self
.assertRaises(TypeError, f
, 10)
263 class TestErrorHandlingPython(TestErrorHandling
):
266 class TestErrorHandlingC(TestErrorHandling
):
269 #==============================================================================
272 Example from the Library Reference: Doc/library/bisect.rst
274 The bisect() function is generally useful for categorizing numeric data.
275 This example uses bisect() to look up a letter grade for an exam total
276 (say) based on a set of ordered numeric breakpoints: 85 and up is an `A',
277 75..84 is a `B', etc.
279 >>> grades = "FEDCBA"
280 >>> breakpoints = [30, 44, 66, 75, 85]
281 >>> from bisect import bisect
282 >>> def grade(total):
283 ... return grades[bisect(breakpoints, total)]
287 >>> map(grade, [33, 99, 77, 44, 12, 88])
288 ['E', 'A', 'B', 'D', 'F', 'A']
292 #------------------------------------------------------------------------------
294 __test__
= {'libreftest' : libreftest
}
296 def test_main(verbose
=None):
297 from test
import test_bisect
299 test_classes
= [TestBisectPython
, TestBisectC
,
300 TestInsortPython
, TestInsortC
,
301 TestErrorHandlingPython
, TestErrorHandlingC
]
303 test_support
.run_unittest(*test_classes
)
304 test_support
.run_doctest(test_bisect
, verbose
)
306 # verify reference counting
307 if verbose
and hasattr(sys
, "gettotalrefcount"):
310 for i
in xrange(len(counts
)):
311 test_support
.run_unittest(*test_classes
)
313 counts
[i
] = sys
.gettotalrefcount()
316 if __name__
== "__main__":
317 test_main(verbose
=True)