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