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