blob: a699d91e38257f2c001ccc29b51ad8c012c2c1b8 [file] [log] [blame]
Christian Heimes1a6387e2008-03-26 12:49:49 +00001"""Unit tests for the bytes and bytearray types.
2
3XXX This is a mess. Common tests should be moved to buffer_tests.py,
4which itself ought to be unified with string_tests.py (and the latter
5should be modernized).
6"""
7
8import os
9import re
10import sys
11import copy
12import pickle
13import tempfile
14import unittest
15import warnings
16import test.test_support
17import test.string_tests
18import test.buffer_tests
19
Georg Brandl3e483f62008-07-16 22:57:41 +000020class Indexable:
21 def __init__(self, value=0):
22 self.value = value
23 def __index__(self):
24 return self.value
25
Christian Heimes1a6387e2008-03-26 12:49:49 +000026
27class BaseBytesTest(unittest.TestCase):
28
29 def setUp(self):
30 self.warning_filters = warnings.filters[:]
31
32 def tearDown(self):
33 warnings.filters = self.warning_filters
34
35 def test_basics(self):
36 b = self.type2test()
37 self.assertEqual(type(b), self.type2test)
38 self.assertEqual(b.__class__, self.type2test)
39
40 def test_empty_sequence(self):
41 b = self.type2test()
42 self.assertEqual(len(b), 0)
43 self.assertRaises(IndexError, lambda: b[0])
44 self.assertRaises(IndexError, lambda: b[1])
45 self.assertRaises(IndexError, lambda: b[sys.maxint])
46 self.assertRaises(IndexError, lambda: b[sys.maxint+1])
47 self.assertRaises(IndexError, lambda: b[10**100])
48 self.assertRaises(IndexError, lambda: b[-1])
49 self.assertRaises(IndexError, lambda: b[-2])
50 self.assertRaises(IndexError, lambda: b[-sys.maxint])
51 self.assertRaises(IndexError, lambda: b[-sys.maxint-1])
52 self.assertRaises(IndexError, lambda: b[-sys.maxint-2])
53 self.assertRaises(IndexError, lambda: b[-10**100])
54
55 def test_from_list(self):
56 ints = list(range(256))
57 b = self.type2test(i for i in ints)
58 self.assertEqual(len(b), 256)
59 self.assertEqual(list(b), ints)
60
61 def test_from_index(self):
Georg Brandl3e483f62008-07-16 22:57:41 +000062 b = self.type2test([Indexable(), Indexable(1), Indexable(254),
63 Indexable(255)])
Christian Heimes1a6387e2008-03-26 12:49:49 +000064 self.assertEqual(list(b), [0, 1, 254, 255])
Benjamin Petersonc218ce82010-04-16 22:43:53 +000065 self.assertRaises(ValueError, self.type2test, [Indexable(-1)])
66 self.assertRaises(ValueError, self.type2test, [Indexable(256)])
Christian Heimes1a6387e2008-03-26 12:49:49 +000067
68 def test_from_ssize(self):
Benjamin Petersonc218ce82010-04-16 22:43:53 +000069 self.assertEqual(self.type2test(0), b'')
70 self.assertEqual(self.type2test(1), b'\x00')
71 self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00')
72 self.assertRaises(ValueError, self.type2test, -1)
Christian Heimes1a6387e2008-03-26 12:49:49 +000073
Benjamin Petersonc218ce82010-04-16 22:43:53 +000074 self.assertEqual(self.type2test('0', 'ascii'), b'0')
75 self.assertEqual(self.type2test(b'0'), b'0')
76 self.assertRaises(OverflowError, self.type2test, sys.maxsize + 1)
Christian Heimes1a6387e2008-03-26 12:49:49 +000077
78 def test_constructor_type_errors(self):
79 self.assertRaises(TypeError, self.type2test, 0.0)
80 class C:
81 pass
Georg Brandl0a34baf2008-07-16 23:18:51 +000082 # allowed in 2.6
83 #self.assertRaises(TypeError, self.type2test, ["0"])
Christian Heimes1a6387e2008-03-26 12:49:49 +000084 self.assertRaises(TypeError, self.type2test, [0.0])
85 self.assertRaises(TypeError, self.type2test, [None])
86 self.assertRaises(TypeError, self.type2test, [C()])
87
88 def test_constructor_value_errors(self):
89 self.assertRaises(ValueError, self.type2test, [-1])
90 self.assertRaises(ValueError, self.type2test, [-sys.maxint])
91 self.assertRaises(ValueError, self.type2test, [-sys.maxint-1])
92 self.assertRaises(ValueError, self.type2test, [-sys.maxint-2])
93 self.assertRaises(ValueError, self.type2test, [-10**100])
94 self.assertRaises(ValueError, self.type2test, [256])
95 self.assertRaises(ValueError, self.type2test, [257])
96 self.assertRaises(ValueError, self.type2test, [sys.maxint])
97 self.assertRaises(ValueError, self.type2test, [sys.maxint+1])
98 self.assertRaises(ValueError, self.type2test, [10**100])
99
100 def test_compare(self):
101 b1 = self.type2test([1, 2, 3])
102 b2 = self.type2test([1, 2, 3])
103 b3 = self.type2test([1, 3])
104
105 self.assertEqual(b1, b2)
106 self.failUnless(b2 != b3)
107 self.failUnless(b1 <= b2)
108 self.failUnless(b1 <= b3)
109 self.failUnless(b1 < b3)
110 self.failUnless(b1 >= b2)
111 self.failUnless(b3 >= b2)
112 self.failUnless(b3 > b2)
113
114 self.failIf(b1 != b2)
115 self.failIf(b2 == b3)
116 self.failIf(b1 > b2)
117 self.failIf(b1 > b3)
118 self.failIf(b1 >= b3)
119 self.failIf(b1 < b2)
120 self.failIf(b3 < b2)
121 self.failIf(b3 <= b2)
122
123 def test_compare_to_str(self):
124 warnings.simplefilter('ignore', BytesWarning)
125 # Byte comparisons with unicode should always fail!
126 # Test this for all expected byte orders and Unicode character sizes
127 self.assertEqual(self.type2test(b"\0a\0b\0c") == u"abc", False)
128 self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == u"abc", False)
129 self.assertEqual(self.type2test(b"a\0b\0c\0") == u"abc", False)
130 self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == u"abc", False)
131 self.assertEqual(self.type2test() == unicode(), False)
132 self.assertEqual(self.type2test() != unicode(), True)
133
134 def test_reversed(self):
135 input = list(map(ord, "Hello"))
136 b = self.type2test(input)
137 output = list(reversed(b))
138 input.reverse()
139 self.assertEqual(output, input)
140
141 def test_getslice(self):
142 def by(s):
143 return self.type2test(map(ord, s))
144 b = by("Hello, world")
145
146 self.assertEqual(b[:5], by("Hello"))
147 self.assertEqual(b[1:5], by("ello"))
148 self.assertEqual(b[5:7], by(", "))
149 self.assertEqual(b[7:], by("world"))
150 self.assertEqual(b[7:12], by("world"))
151 self.assertEqual(b[7:100], by("world"))
152
153 self.assertEqual(b[:-7], by("Hello"))
154 self.assertEqual(b[-11:-7], by("ello"))
155 self.assertEqual(b[-7:-5], by(", "))
156 self.assertEqual(b[-5:], by("world"))
157 self.assertEqual(b[-5:12], by("world"))
158 self.assertEqual(b[-5:100], by("world"))
159 self.assertEqual(b[-100:5], by("Hello"))
160
161 def test_extended_getslice(self):
162 # Test extended slicing by comparing with list slicing.
163 L = list(range(255))
164 b = self.type2test(L)
165 indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
166 for start in indices:
167 for stop in indices:
168 # Skip step 0 (invalid)
169 for step in indices[1:]:
170 self.assertEqual(b[start:stop:step], self.type2test(L[start:stop:step]))
171
172 def test_encoding(self):
173 sample = u"Hello world\n\u1234\u5678\u9abc\udef0"
174 for enc in ("utf8", "utf16"):
175 b = self.type2test(sample, enc)
176 self.assertEqual(b, self.type2test(sample.encode(enc)))
177 self.assertRaises(UnicodeEncodeError, self.type2test, sample, "latin1")
178 b = self.type2test(sample, "latin1", "ignore")
179 self.assertEqual(b, self.type2test(sample[:-4], "utf-8"))
180
181 def test_decode(self):
182 sample = u"Hello world\n\u1234\u5678\u9abc\def0\def0"
183 for enc in ("utf8", "utf16"):
184 b = self.type2test(sample, enc)
185 self.assertEqual(b.decode(enc), sample)
186 sample = u"Hello world\n\x80\x81\xfe\xff"
187 b = self.type2test(sample, "latin1")
188 self.assertRaises(UnicodeDecodeError, b.decode, "utf8")
189 self.assertEqual(b.decode("utf8", "ignore"), "Hello world\n")
190
191 def test_from_int(self):
192 b = self.type2test(0)
193 self.assertEqual(b, self.type2test())
194 b = self.type2test(10)
195 self.assertEqual(b, self.type2test([0]*10))
196 b = self.type2test(10000)
197 self.assertEqual(b, self.type2test([0]*10000))
198
199 def test_concat(self):
200 b1 = self.type2test(b"abc")
201 b2 = self.type2test(b"def")
202 self.assertEqual(b1 + b2, b"abcdef")
203 self.assertEqual(b1 + bytes(b"def"), b"abcdef")
204 self.assertEqual(bytes(b"def") + b1, b"defabc")
205 self.assertRaises(TypeError, lambda: b1 + u"def")
206 self.assertRaises(TypeError, lambda: u"abc" + b2)
207
208 def test_repeat(self):
209 for b in b"abc", self.type2test(b"abc"):
210 self.assertEqual(b * 3, b"abcabcabc")
211 self.assertEqual(b * 0, b"")
212 self.assertEqual(b * -1, b"")
213 self.assertRaises(TypeError, lambda: b * 3.14)
214 self.assertRaises(TypeError, lambda: 3.14 * b)
215 # XXX Shouldn't bytes and bytearray agree on what to raise?
216 self.assertRaises((OverflowError, MemoryError),
Mark Hammond69ed5242008-08-23 00:59:14 +0000217 lambda: b * sys.maxsize)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000218
219 def test_repeat_1char(self):
220 self.assertEqual(self.type2test(b'x')*100, self.type2test([ord('x')]*100))
221
222 def test_contains(self):
223 b = self.type2test(b"abc")
224 self.failUnless(ord('a') in b)
225 self.failUnless(int(ord('a')) in b)
226 self.failIf(200 in b)
227 self.failIf(200 in b)
228 self.assertRaises(ValueError, lambda: 300 in b)
229 self.assertRaises(ValueError, lambda: -1 in b)
230 self.assertRaises(TypeError, lambda: None in b)
231 self.assertRaises(TypeError, lambda: float(ord('a')) in b)
232 self.assertRaises(TypeError, lambda: u"a" in b)
233 for f in bytes, bytearray:
234 self.failUnless(f(b"") in b)
235 self.failUnless(f(b"a") in b)
236 self.failUnless(f(b"b") in b)
237 self.failUnless(f(b"c") in b)
238 self.failUnless(f(b"ab") in b)
239 self.failUnless(f(b"bc") in b)
240 self.failUnless(f(b"abc") in b)
241 self.failIf(f(b"ac") in b)
242 self.failIf(f(b"d") in b)
243 self.failIf(f(b"dab") in b)
244 self.failIf(f(b"abd") in b)
245
246 def test_fromhex(self):
247 self.assertRaises(TypeError, self.type2test.fromhex)
248 self.assertRaises(TypeError, self.type2test.fromhex, 1)
249 self.assertEquals(self.type2test.fromhex(u''), self.type2test())
250 b = bytearray([0x1a, 0x2b, 0x30])
251 self.assertEquals(self.type2test.fromhex(u'1a2B30'), b)
252 self.assertEquals(self.type2test.fromhex(u' 1A 2B 30 '), b)
253 self.assertEquals(self.type2test.fromhex(u'0000'), b'\0\0')
254 self.assertRaises(TypeError, self.type2test.fromhex, b'1B')
255 self.assertRaises(ValueError, self.type2test.fromhex, u'a')
256 self.assertRaises(ValueError, self.type2test.fromhex, u'rt')
257 self.assertRaises(ValueError, self.type2test.fromhex, u'1a b cd')
258 self.assertRaises(ValueError, self.type2test.fromhex, u'\x00')
259 self.assertRaises(ValueError, self.type2test.fromhex, u'12 \x00 34')
260
261 def test_join(self):
262 self.assertEqual(self.type2test(b"").join([]), b"")
263 self.assertEqual(self.type2test(b"").join([b""]), b"")
264 for lst in [[b"abc"], [b"a", b"bc"], [b"ab", b"c"], [b"a", b"b", b"c"]]:
265 lst = list(map(self.type2test, lst))
266 self.assertEqual(self.type2test(b"").join(lst), b"abc")
267 self.assertEqual(self.type2test(b"").join(tuple(lst)), b"abc")
268 self.assertEqual(self.type2test(b"").join(iter(lst)), b"abc")
269 self.assertEqual(self.type2test(b".").join([b"ab", b"cd"]), b"ab.cd")
270 # XXX more...
271
272 def test_index(self):
273 b = self.type2test(b'parrot')
274 self.assertEqual(b.index('p'), 0)
275 self.assertEqual(b.index('rr'), 2)
276 self.assertEqual(b.index('t'), 5)
277 self.assertRaises(ValueError, lambda: b.index('w'))
278
279 def test_count(self):
280 b = self.type2test(b'mississippi')
281 self.assertEqual(b.count(b'i'), 4)
282 self.assertEqual(b.count(b'ss'), 2)
283 self.assertEqual(b.count(b'w'), 0)
284
285 def test_startswith(self):
286 b = self.type2test(b'hello')
287 self.assertFalse(self.type2test().startswith(b"anything"))
288 self.assertTrue(b.startswith(b"hello"))
289 self.assertTrue(b.startswith(b"hel"))
290 self.assertTrue(b.startswith(b"h"))
291 self.assertFalse(b.startswith(b"hellow"))
292 self.assertFalse(b.startswith(b"ha"))
293
294 def test_endswith(self):
295 b = self.type2test(b'hello')
296 self.assertFalse(bytearray().endswith(b"anything"))
297 self.assertTrue(b.endswith(b"hello"))
298 self.assertTrue(b.endswith(b"llo"))
299 self.assertTrue(b.endswith(b"o"))
300 self.assertFalse(b.endswith(b"whello"))
301 self.assertFalse(b.endswith(b"no"))
302
303 def test_find(self):
304 b = self.type2test(b'mississippi')
305 self.assertEqual(b.find(b'ss'), 2)
306 self.assertEqual(b.find(b'ss', 3), 5)
307 self.assertEqual(b.find(b'ss', 1, 7), 2)
308 self.assertEqual(b.find(b'ss', 1, 3), -1)
309 self.assertEqual(b.find(b'w'), -1)
310 self.assertEqual(b.find(b'mississippian'), -1)
311
312 def test_rfind(self):
313 b = self.type2test(b'mississippi')
314 self.assertEqual(b.rfind(b'ss'), 5)
315 self.assertEqual(b.rfind(b'ss', 3), 5)
316 self.assertEqual(b.rfind(b'ss', 0, 6), 2)
317 self.assertEqual(b.rfind(b'w'), -1)
318 self.assertEqual(b.rfind(b'mississippian'), -1)
319
320 def test_index(self):
321 b = self.type2test(b'world')
322 self.assertEqual(b.index(b'w'), 0)
323 self.assertEqual(b.index(b'orl'), 1)
324 self.assertRaises(ValueError, b.index, b'worm')
325 self.assertRaises(ValueError, b.index, b'ldo')
326
327 def test_rindex(self):
328 # XXX could be more rigorous
329 b = self.type2test(b'world')
330 self.assertEqual(b.rindex(b'w'), 0)
331 self.assertEqual(b.rindex(b'orl'), 1)
332 self.assertRaises(ValueError, b.rindex, b'worm')
333 self.assertRaises(ValueError, b.rindex, b'ldo')
334
335 def test_replace(self):
336 b = self.type2test(b'mississippi')
337 self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
338 self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
339
340 def test_split(self):
341 b = self.type2test(b'mississippi')
342 self.assertEqual(b.split(b'i'), [b'm', b'ss', b'ss', b'pp', b''])
343 self.assertEqual(b.split(b'ss'), [b'mi', b'i', b'ippi'])
344 self.assertEqual(b.split(b'w'), [b])
345
346 def test_split_whitespace(self):
347 for b in (b' arf barf ', b'arf\tbarf', b'arf\nbarf', b'arf\rbarf',
348 b'arf\fbarf', b'arf\vbarf'):
349 b = self.type2test(b)
350 self.assertEqual(b.split(), [b'arf', b'barf'])
351 self.assertEqual(b.split(None), [b'arf', b'barf'])
352 self.assertEqual(b.split(None, 2), [b'arf', b'barf'])
353 for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
354 b = self.type2test(b)
355 self.assertEqual(b.split(), [b])
356 self.assertEqual(self.type2test(b' a bb c ').split(None, 0), [b'a bb c '])
357 self.assertEqual(self.type2test(b' a bb c ').split(None, 1), [b'a', b'bb c '])
358 self.assertEqual(self.type2test(b' a bb c ').split(None, 2), [b'a', b'bb', b'c '])
359 self.assertEqual(self.type2test(b' a bb c ').split(None, 3), [b'a', b'bb', b'c'])
360
361 def test_split_string_error(self):
362 self.assertRaises(TypeError, self.type2test(b'a b').split, u' ')
363
364 def test_rsplit(self):
365 b = self.type2test(b'mississippi')
366 self.assertEqual(b.rsplit(b'i'), [b'm', b'ss', b'ss', b'pp', b''])
367 self.assertEqual(b.rsplit(b'ss'), [b'mi', b'i', b'ippi'])
368 self.assertEqual(b.rsplit(b'w'), [b])
369
370 def test_rsplit_whitespace(self):
371 for b in (b' arf barf ', b'arf\tbarf', b'arf\nbarf', b'arf\rbarf',
372 b'arf\fbarf', b'arf\vbarf'):
373 b = self.type2test(b)
374 self.assertEqual(b.rsplit(), [b'arf', b'barf'])
375 self.assertEqual(b.rsplit(None), [b'arf', b'barf'])
376 self.assertEqual(b.rsplit(None, 2), [b'arf', b'barf'])
377 self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 0), [b' a bb c'])
378 self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 1), [b' a bb', b'c'])
379 self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 2), [b' a', b'bb', b'c'])
380 self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 3), [b'a', b'bb', b'c'])
381
382 def test_rsplit_string_error(self):
383 self.assertRaises(TypeError, self.type2test(b'a b').rsplit, u' ')
384
385 def test_rsplit_unicodewhitespace(self):
386 b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
387 self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
388 self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
389
390 def test_partition(self):
391 b = self.type2test(b'mississippi')
392 self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi'))
393 self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
394
395 def test_rpartition(self):
396 b = self.type2test(b'mississippi')
397 self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi'))
398 self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
399
400 def test_pickling(self):
Georg Brandl4aef7032008-11-07 08:56:27 +0000401 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Christian Heimes1a6387e2008-03-26 12:49:49 +0000402 for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
403 b = self.type2test(b)
404 ps = pickle.dumps(b, proto)
405 q = pickle.loads(ps)
406 self.assertEqual(b, q)
407
408 def test_strip(self):
409 b = self.type2test(b'mississippi')
410 self.assertEqual(b.strip(b'i'), b'mississipp')
411 self.assertEqual(b.strip(b'm'), b'ississippi')
412 self.assertEqual(b.strip(b'pi'), b'mississ')
413 self.assertEqual(b.strip(b'im'), b'ssissipp')
414 self.assertEqual(b.strip(b'pim'), b'ssiss')
415 self.assertEqual(b.strip(b), b'')
416
417 def test_lstrip(self):
418 b = self.type2test(b'mississippi')
419 self.assertEqual(b.lstrip(b'i'), b'mississippi')
420 self.assertEqual(b.lstrip(b'm'), b'ississippi')
421 self.assertEqual(b.lstrip(b'pi'), b'mississippi')
422 self.assertEqual(b.lstrip(b'im'), b'ssissippi')
423 self.assertEqual(b.lstrip(b'pim'), b'ssissippi')
424
425 def test_rstrip(self):
426 b = self.type2test(b'mississippi')
427 self.assertEqual(b.rstrip(b'i'), b'mississipp')
428 self.assertEqual(b.rstrip(b'm'), b'mississippi')
429 self.assertEqual(b.rstrip(b'pi'), b'mississ')
430 self.assertEqual(b.rstrip(b'im'), b'mississipp')
431 self.assertEqual(b.rstrip(b'pim'), b'mississ')
432
433 def test_strip_whitespace(self):
434 b = self.type2test(b' \t\n\r\f\vabc \t\n\r\f\v')
435 self.assertEqual(b.strip(), b'abc')
436 self.assertEqual(b.lstrip(), b'abc \t\n\r\f\v')
437 self.assertEqual(b.rstrip(), b' \t\n\r\f\vabc')
438
439 def XXXtest_strip_bytearray(self):
440 # XXX memoryview not available
441 self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b')
442 self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc')
443 self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
444
445 def test_strip_string_error(self):
446 self.assertRaises(TypeError, self.type2test(b'abc').strip, u'b')
447 self.assertRaises(TypeError, self.type2test(b'abc').lstrip, u'b')
448 self.assertRaises(TypeError, self.type2test(b'abc').rstrip, u'b')
449
450 def test_ord(self):
451 b = self.type2test(b'\0A\x7f\x80\xff')
452 self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
453 [0, 65, 127, 128, 255])
454
455
456class ByteArrayTest(BaseBytesTest):
457 type2test = bytearray
458
459 def test_nohash(self):
460 self.assertRaises(TypeError, hash, bytearray())
461
462 def test_bytearray_api(self):
463 short_sample = b"Hello world\n"
464 sample = short_sample + b"\0"*(20 - len(short_sample))
465 tfn = tempfile.mktemp()
466 try:
467 # Prepare
468 with open(tfn, "wb") as f:
469 f.write(short_sample)
470 # Test readinto
471 with open(tfn, "rb") as f:
472 b = bytearray(20)
473 n = f.readinto(b)
474 self.assertEqual(n, len(short_sample))
475 # Python 2.x
476 b_sample = (ord(s) for s in sample)
477 self.assertEqual(list(b), list(b_sample))
478 # Test writing in binary mode
479 with open(tfn, "wb") as f:
480 f.write(b)
481 with open(tfn, "rb") as f:
482 self.assertEqual(f.read(), sample)
483 # Text mode is ambiguous; don't test
484 finally:
485 try:
486 os.remove(tfn)
487 except os.error:
488 pass
489
490 def test_reverse(self):
491 b = bytearray(b'hello')
492 self.assertEqual(b.reverse(), None)
493 self.assertEqual(b, b'olleh')
494 b = bytearray(b'hello1') # test even number of items
495 b.reverse()
496 self.assertEqual(b, b'1olleh')
497 b = bytearray()
498 b.reverse()
499 self.assertFalse(b)
500
501 def test_regexps(self):
502 def by(s):
503 return bytearray(map(ord, s))
504 b = by("Hello, world")
505 self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")])
506
507 def test_setitem(self):
508 b = bytearray([1, 2, 3])
509 b[1] = 100
510 self.assertEqual(b, bytearray([1, 100, 3]))
511 b[-1] = 200
512 self.assertEqual(b, bytearray([1, 100, 200]))
Georg Brandl3e483f62008-07-16 22:57:41 +0000513 b[0] = Indexable(10)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000514 self.assertEqual(b, bytearray([10, 100, 200]))
515 try:
516 b[3] = 0
517 self.fail("Didn't raise IndexError")
518 except IndexError:
519 pass
520 try:
521 b[-10] = 0
522 self.fail("Didn't raise IndexError")
523 except IndexError:
524 pass
525 try:
526 b[0] = 256
527 self.fail("Didn't raise ValueError")
528 except ValueError:
529 pass
530 try:
Georg Brandl3e483f62008-07-16 22:57:41 +0000531 b[0] = Indexable(-1)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000532 self.fail("Didn't raise ValueError")
533 except ValueError:
534 pass
535 try:
536 b[0] = None
537 self.fail("Didn't raise TypeError")
538 except TypeError:
539 pass
540
541 def test_delitem(self):
542 b = bytearray(range(10))
543 del b[0]
544 self.assertEqual(b, bytearray(range(1, 10)))
545 del b[-1]
546 self.assertEqual(b, bytearray(range(1, 9)))
547 del b[4]
548 self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
549
550 def test_setslice(self):
551 b = bytearray(range(10))
552 self.assertEqual(list(b), list(range(10)))
553
554 b[0:5] = bytearray([1, 1, 1, 1, 1])
555 self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
556
557 del b[0:-5]
558 self.assertEqual(b, bytearray([5, 6, 7, 8, 9]))
559
560 b[0:0] = bytearray([0, 1, 2, 3, 4])
561 self.assertEqual(b, bytearray(range(10)))
562
563 b[-7:-3] = bytearray([100, 101])
564 self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9]))
565
566 b[3:5] = [3, 4, 5, 6]
567 self.assertEqual(b, bytearray(range(10)))
568
569 b[3:0] = [42, 42, 42]
570 self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
571
572 def test_extended_set_del_slice(self):
Mark Dickinson02733542010-01-29 17:16:18 +0000573 indices = (0, None, 1, 3, 19, 300, 1<<333, -1, -2, -31, -300)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000574 for start in indices:
575 for stop in indices:
576 # Skip invalid step 0
577 for step in indices[1:]:
578 L = list(range(255))
579 b = bytearray(L)
580 # Make sure we have a slice of exactly the right length,
581 # but with different data.
582 data = L[start:stop:step]
583 data.reverse()
584 L[start:stop:step] = data
585 b[start:stop:step] = data
586 self.assertEquals(b, bytearray(L))
587
588 del L[start:stop:step]
589 del b[start:stop:step]
590 self.assertEquals(b, bytearray(L))
591
592 def test_setslice_trap(self):
593 # This test verifies that we correctly handle assigning self
594 # to a slice of self (the old Lambert Meertens trap).
595 b = bytearray(range(256))
596 b[8:] = b
597 self.assertEqual(b, bytearray(list(range(8)) + list(range(256))))
598
599 def test_iconcat(self):
600 b = bytearray(b"abc")
601 b1 = b
602 b += b"def"
603 self.assertEqual(b, b"abcdef")
604 self.assertEqual(b, b1)
605 self.failUnless(b is b1)
606 b += b"xyz"
607 self.assertEqual(b, b"abcdefxyz")
608 try:
609 b += u""
610 except TypeError:
611 pass
612 else:
613 self.fail("bytes += unicode didn't raise TypeError")
614
615 def test_irepeat(self):
616 b = bytearray(b"abc")
617 b1 = b
618 b *= 3
619 self.assertEqual(b, b"abcabcabc")
620 self.assertEqual(b, b1)
621 self.failUnless(b is b1)
622
623 def test_irepeat_1char(self):
624 b = bytearray(b"x")
625 b1 = b
626 b *= 100
627 self.assertEqual(b, b"x"*100)
628 self.assertEqual(b, b1)
629 self.failUnless(b is b1)
630
631 def test_alloc(self):
632 b = bytearray()
633 alloc = b.__alloc__()
634 self.assert_(alloc >= 0)
635 seq = [alloc]
636 for i in range(100):
637 b += b"x"
638 alloc = b.__alloc__()
639 self.assert_(alloc >= len(b))
640 if alloc not in seq:
641 seq.append(alloc)
642
643 def test_extend(self):
644 orig = b'hello'
645 a = bytearray(orig)
646 a.extend(a)
647 self.assertEqual(a, orig + orig)
648 self.assertEqual(a[5:], orig)
649 a = bytearray(b'')
650 # Test iterators that don't have a __length_hint__
651 a.extend(map(ord, orig * 25))
652 a.extend(ord(x) for x in orig * 25)
653 self.assertEqual(a, orig * 50)
654 self.assertEqual(a[-5:], orig)
655 a = bytearray(b'')
656 a.extend(iter(map(ord, orig * 50)))
657 self.assertEqual(a, orig * 50)
658 self.assertEqual(a[-5:], orig)
659 a = bytearray(b'')
660 a.extend(list(map(ord, orig * 50)))
661 self.assertEqual(a, orig * 50)
662 self.assertEqual(a[-5:], orig)
663 a = bytearray(b'')
664 self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
665 self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
666 self.assertEqual(len(a), 0)
Georg Brandl3e483f62008-07-16 22:57:41 +0000667 a = bytearray(b'')
668 a.extend([Indexable(ord('a'))])
669 self.assertEqual(a, b'a')
Christian Heimes1a6387e2008-03-26 12:49:49 +0000670
671 def test_remove(self):
672 b = bytearray(b'hello')
673 b.remove(ord('l'))
674 self.assertEqual(b, b'helo')
675 b.remove(ord('l'))
676 self.assertEqual(b, b'heo')
677 self.assertRaises(ValueError, lambda: b.remove(ord('l')))
678 self.assertRaises(ValueError, lambda: b.remove(400))
679 self.assertRaises(TypeError, lambda: b.remove(u'e'))
680 # remove first and last
681 b.remove(ord('o'))
682 b.remove(ord('h'))
683 self.assertEqual(b, b'e')
684 self.assertRaises(TypeError, lambda: b.remove(u'e'))
Georg Brandl3e483f62008-07-16 22:57:41 +0000685 b.remove(Indexable(ord('e')))
686 self.assertEqual(b, b'')
Christian Heimes1a6387e2008-03-26 12:49:49 +0000687
688 def test_pop(self):
689 b = bytearray(b'world')
690 self.assertEqual(b.pop(), ord('d'))
691 self.assertEqual(b.pop(0), ord('w'))
692 self.assertEqual(b.pop(-2), ord('r'))
693 self.assertRaises(IndexError, lambda: b.pop(10))
694 self.assertRaises(OverflowError, lambda: bytearray().pop())
Mark Dickinsonb61c0352009-09-06 10:05:28 +0000695 # test for issue #6846
696 self.assertEqual(bytearray(b'\xff').pop(), 0xff)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000697
698 def test_nosort(self):
699 self.assertRaises(AttributeError, lambda: bytearray().sort())
700
701 def test_append(self):
702 b = bytearray(b'hell')
703 b.append(ord('o'))
704 self.assertEqual(b, b'hello')
705 self.assertEqual(b.append(100), None)
706 b = bytearray()
707 b.append(ord('A'))
708 self.assertEqual(len(b), 1)
709 self.assertRaises(TypeError, lambda: b.append(u'o'))
Georg Brandl3e483f62008-07-16 22:57:41 +0000710 b = bytearray()
711 b.append(Indexable(ord('A')))
712 self.assertEqual(b, b'A')
Christian Heimes1a6387e2008-03-26 12:49:49 +0000713
714 def test_insert(self):
715 b = bytearray(b'msssspp')
716 b.insert(1, ord('i'))
717 b.insert(4, ord('i'))
718 b.insert(-2, ord('i'))
719 b.insert(1000, ord('i'))
720 self.assertEqual(b, b'mississippi')
Georg Brandl3e483f62008-07-16 22:57:41 +0000721 # allowed in 2.6
722 #self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
723 b = bytearray()
724 b.insert(0, Indexable(ord('A')))
725 self.assertEqual(b, b'A')
Christian Heimes1a6387e2008-03-26 12:49:49 +0000726
Benjamin Peterson866eba92008-11-19 22:05:53 +0000727 def test_copied(self):
728 # Issue 4348. Make sure that operations that don't mutate the array
729 # copy the bytes.
730 b = bytearray(b'abc')
Georg Brandld2094602008-12-05 08:51:30 +0000731 self.assertFalse(b is b.replace(b'abc', b'cde', 0))
Benjamin Peterson866eba92008-11-19 22:05:53 +0000732
733 t = bytearray([i for i in range(256)])
734 x = bytearray(b'')
735 self.assertFalse(x is x.translate(t))
736
Christian Heimes1a6387e2008-03-26 12:49:49 +0000737 def test_partition_bytearray_doesnt_share_nullstring(self):
738 a, b, c = bytearray(b"x").partition(b"y")
739 self.assertEqual(b, b"")
740 self.assertEqual(c, b"")
741 self.assert_(b is not c)
742 b += b"!"
743 self.assertEqual(c, b"")
744 a, b, c = bytearray(b"x").partition(b"y")
745 self.assertEqual(b, b"")
746 self.assertEqual(c, b"")
747 # Same for rpartition
748 b, c, a = bytearray(b"x").rpartition(b"y")
749 self.assertEqual(b, b"")
750 self.assertEqual(c, b"")
751 self.assert_(b is not c)
752 b += b"!"
753 self.assertEqual(c, b"")
754 c, b, a = bytearray(b"x").rpartition(b"y")
755 self.assertEqual(b, b"")
756 self.assertEqual(c, b"")
757
Antoine Pitrou599db7f2008-12-07 00:07:51 +0000758 # XXX memoryview not available
759 def XXXtest_resize_forbidden(self):
760 # #4509: can't resize a bytearray when there are buffer exports, even
761 # if it wouldn't reallocate the underlying buffer.
762 # Furthermore, no destructive changes to the buffer may be applied
763 # before raising the error.
764 b = bytearray(range(10))
765 v = memoryview(b)
766 def resize(n):
767 b[1:-1] = range(n + 1, 2*n - 1)
768 resize(10)
769 orig = b[:]
770 self.assertRaises(BufferError, resize, 11)
771 self.assertEquals(b, orig)
772 self.assertRaises(BufferError, resize, 9)
773 self.assertEquals(b, orig)
774 self.assertRaises(BufferError, resize, 0)
775 self.assertEquals(b, orig)
776 # Other operations implying resize
777 self.assertRaises(BufferError, b.pop, 0)
778 self.assertEquals(b, orig)
779 self.assertRaises(BufferError, b.remove, b[1])
780 self.assertEquals(b, orig)
781 def delitem():
782 del b[1]
783 self.assertRaises(BufferError, delitem)
784 self.assertEquals(b, orig)
785 # deleting a non-contiguous slice
786 def delslice():
787 b[1:-1:2] = b""
788 self.assertRaises(BufferError, delslice)
789 self.assertEquals(b, orig)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000790
Antoine Pitroubb667d42010-01-17 12:31:10 +0000791 def test_empty_bytearray(self):
792 # Issue #7561: operations on empty bytearrays could crash in many
793 # situations, due to a fragile implementation of the
794 # PyByteArray_AS_STRING() C macro.
795 self.assertRaises(ValueError, int, bytearray(b''))
796
797
Christian Heimes1a6387e2008-03-26 12:49:49 +0000798class AssortedBytesTest(unittest.TestCase):
799 #
800 # Test various combinations of bytes and bytearray
801 #
802
803 def setUp(self):
804 self.warning_filters = warnings.filters[:]
805
806 def tearDown(self):
807 warnings.filters = self.warning_filters
808
809 def test_repr_str(self):
810 warnings.simplefilter('ignore', BytesWarning)
811 for f in str, repr:
812 self.assertEqual(f(bytearray()), "bytearray(b'')")
813 self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
814 self.assertEqual(f(bytearray([0, 1, 254, 255])),
815 "bytearray(b'\\x00\\x01\\xfe\\xff')")
816 self.assertEqual(f(b"abc"), "b'abc'")
817 self.assertEqual(f(b"'"), '''b"'"''') # '''
818 self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
819
820 def test_compare_bytes_to_bytearray(self):
821 self.assertEqual(b"abc" == bytes(b"abc"), True)
822 self.assertEqual(b"ab" != bytes(b"abc"), True)
823 self.assertEqual(b"ab" <= bytes(b"abc"), True)
824 self.assertEqual(b"ab" < bytes(b"abc"), True)
825 self.assertEqual(b"abc" >= bytes(b"ab"), True)
826 self.assertEqual(b"abc" > bytes(b"ab"), True)
827
828 self.assertEqual(b"abc" != bytes(b"abc"), False)
829 self.assertEqual(b"ab" == bytes(b"abc"), False)
830 self.assertEqual(b"ab" > bytes(b"abc"), False)
831 self.assertEqual(b"ab" >= bytes(b"abc"), False)
832 self.assertEqual(b"abc" < bytes(b"ab"), False)
833 self.assertEqual(b"abc" <= bytes(b"ab"), False)
834
835 self.assertEqual(bytes(b"abc") == b"abc", True)
836 self.assertEqual(bytes(b"ab") != b"abc", True)
837 self.assertEqual(bytes(b"ab") <= b"abc", True)
838 self.assertEqual(bytes(b"ab") < b"abc", True)
839 self.assertEqual(bytes(b"abc") >= b"ab", True)
840 self.assertEqual(bytes(b"abc") > b"ab", True)
841
842 self.assertEqual(bytes(b"abc") != b"abc", False)
843 self.assertEqual(bytes(b"ab") == b"abc", False)
844 self.assertEqual(bytes(b"ab") > b"abc", False)
845 self.assertEqual(bytes(b"ab") >= b"abc", False)
846 self.assertEqual(bytes(b"abc") < b"ab", False)
847 self.assertEqual(bytes(b"abc") <= b"ab", False)
848
849 def test_doc(self):
850 self.failUnless(bytearray.__doc__ != None)
851 self.failUnless(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__)
852 self.failUnless(bytes.__doc__ != None)
853 self.failUnless(bytes.__doc__.startswith("bytes("), bytes.__doc__)
854
855 def test_from_bytearray(self):
856 sample = bytes(b"Hello world\n\x80\x81\xfe\xff")
857 buf = memoryview(sample)
858 b = bytearray(buf)
859 self.assertEqual(b, bytearray(sample))
860
861 def test_to_str(self):
862 warnings.simplefilter('ignore', BytesWarning)
863 self.assertEqual(str(b''), "b''")
864 self.assertEqual(str(b'x'), "b'x'")
865 self.assertEqual(str(b'\x80'), "b'\\x80'")
866 self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
867 self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
868 self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
869
870 def test_literal(self):
871 tests = [
872 (b"Wonderful spam", "Wonderful spam"),
873 (br"Wonderful spam too", "Wonderful spam too"),
874 (b"\xaa\x00\000\200", "\xaa\x00\000\200"),
875 (br"\xaa\x00\000\200", r"\xaa\x00\000\200"),
876 ]
877 for b, s in tests:
878 self.assertEqual(b, bytearray(s, 'latin-1'))
879 for c in range(128, 256):
880 self.assertRaises(SyntaxError, eval,
881 'b"%s"' % chr(c))
882
883 def test_translate(self):
884 b = b'hello'
Georg Brandlef29f862008-12-28 11:55:24 +0000885 ba = bytearray(b)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000886 rosetta = bytearray(range(0, 256))
887 rosetta[ord('o')] = ord('e')
888 c = b.translate(rosetta, b'l')
889 self.assertEqual(b, b'hello')
890 self.assertEqual(c, b'hee')
Georg Brandlef29f862008-12-28 11:55:24 +0000891 c = ba.translate(rosetta, b'l')
892 self.assertEqual(ba, b'hello')
893 self.assertEqual(c, b'hee')
894 c = b.translate(None, b'e')
895 self.assertEqual(c, b'hllo')
896 self.assertRaises(TypeError, b.translate, b'a'*256, None)
897 self.assertRaises(TypeError, ba.translate, b'a'*256, None)
Christian Heimes1a6387e2008-03-26 12:49:49 +0000898
899 def test_split_bytearray(self):
900 self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b'])
901
902 def test_rsplit_bytearray(self):
903 self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b'])
904
905 # Optimizations:
906 # __iter__? (optimization)
907 # __reversed__? (optimization)
908
909 # XXX More string methods? (Those that don't use character properties)
910
911 # There are tests in string_tests.py that are more
912 # comprehensive for things like split, partition, etc.
913 # Unfortunately they are all bundled with tests that
914 # are not appropriate for bytes
915
916 # I've started porting some of those into bytearray_tests.py, we should port
917 # the rest that make sense (the code can be cleaned up to use modern
918 # unittest methods at the same time).
919
920class BytearrayPEP3137Test(unittest.TestCase,
921 test.buffer_tests.MixinBytesBufferCommonTests):
922 def marshal(self, x):
923 return bytearray(x)
924
925 def test_returns_new_copy(self):
926 val = self.marshal(b'1234')
927 # On immutable types these MAY return a reference to themselves
928 # but on mutable types like bytearray they MUST return a new copy.
929 for methname in ('zfill', 'rjust', 'ljust', 'center'):
930 method = getattr(val, methname)
931 newval = method(3)
932 self.assertEqual(val, newval)
933 self.assertTrue(val is not newval,
934 methname+' returned self on a mutable object')
935
936
937class FixedStringTest(test.string_tests.BaseTest):
938
939 def fixtype(self, obj):
940 if isinstance(obj, str):
941 return obj.encode("utf-8")
942 return super(FixedStringTest, self).fixtype(obj)
943
944 # Currently the bytes containment testing uses a single integer
945 # value. This may not be the final design, but until then the
946 # bytes section with in a bytes containment not valid
947 def test_contains(self):
948 pass
949 def test_expandtabs(self):
950 pass
951 def test_upper(self):
952 pass
953 def test_lower(self):
954 pass
955 def test_hash(self):
956 # XXX check this out
957 pass
958
959
960class ByteArrayAsStringTest(FixedStringTest):
961 type2test = bytearray
962
963
964class ByteArraySubclass(bytearray):
965 pass
966
967class ByteArraySubclassTest(unittest.TestCase):
968
969 def test_basic(self):
970 self.assert_(issubclass(ByteArraySubclass, bytearray))
971 self.assert_(isinstance(ByteArraySubclass(), bytearray))
972
973 a, b = b"abcd", b"efgh"
974 _a, _b = ByteArraySubclass(a), ByteArraySubclass(b)
975
976 # test comparison operators with subclass instances
977 self.assert_(_a == _a)
978 self.assert_(_a != _b)
979 self.assert_(_a < _b)
980 self.assert_(_a <= _b)
981 self.assert_(_b >= _a)
982 self.assert_(_b > _a)
983 self.assert_(_a is not a)
984
985 # test concat of subclass instances
986 self.assertEqual(a + b, _a + _b)
987 self.assertEqual(a + b, a + _b)
988 self.assertEqual(a + b, _a + b)
989
990 # test repeat
991 self.assert_(a*5 == _a*5)
992
993 def test_join(self):
994 # Make sure join returns a NEW object for single item sequences
995 # involving a subclass.
996 # Make sure that it is of the appropriate type.
997 s1 = ByteArraySubclass(b"abcd")
998 s2 = bytearray().join([s1])
999 self.assert_(s1 is not s2)
1000 self.assert_(type(s2) is bytearray, type(s2))
1001
1002 # Test reverse, calling join on subclass
1003 s3 = s1.join([b"abcd"])
1004 self.assert_(type(s3) is bytearray)
1005
1006 def test_pickle(self):
1007 a = ByteArraySubclass(b"abcd")
1008 a.x = 10
1009 a.y = ByteArraySubclass(b"efgh")
Georg Brandl4aef7032008-11-07 08:56:27 +00001010 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Christian Heimes1a6387e2008-03-26 12:49:49 +00001011 b = pickle.loads(pickle.dumps(a, proto))
1012 self.assertNotEqual(id(a), id(b))
1013 self.assertEqual(a, b)
1014 self.assertEqual(a.x, b.x)
1015 self.assertEqual(a.y, b.y)
1016 self.assertEqual(type(a), type(b))
1017 self.assertEqual(type(a.y), type(b.y))
1018
1019 def test_copy(self):
1020 a = ByteArraySubclass(b"abcd")
1021 a.x = 10
1022 a.y = ByteArraySubclass(b"efgh")
1023 for copy_method in (copy.copy, copy.deepcopy):
1024 b = copy_method(a)
1025 self.assertNotEqual(id(a), id(b))
1026 self.assertEqual(a, b)
1027 self.assertEqual(a.x, b.x)
1028 self.assertEqual(a.y, b.y)
1029 self.assertEqual(type(a), type(b))
1030 self.assertEqual(type(a.y), type(b.y))
1031
1032 def test_init_override(self):
1033 class subclass(bytearray):
1034 def __init__(self, newarg=1, *args, **kwargs):
1035 bytearray.__init__(self, *args, **kwargs)
1036 x = subclass(4, source=b"abcd")
1037 self.assertEqual(x, b"abcd")
1038 x = subclass(newarg=4, source=b"abcd")
1039 self.assertEqual(x, b"abcd")
1040
1041def test_main():
1042 #test.test_support.run_unittest(BytesTest)
1043 #test.test_support.run_unittest(AssortedBytesTest)
1044 #test.test_support.run_unittest(BytesAsStringTest)
1045 test.test_support.run_unittest(
1046 ByteArrayTest,
1047 ByteArrayAsStringTest,
1048 ByteArraySubclassTest,
1049 BytearrayPEP3137Test)
1050
1051if __name__ == "__main__":
1052 test_main()