• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_split_string_error(self):
340        self.assertRaises(TypeError, self.type2test(b'a b').split, u' ')
341
342    def test_split_unicodewhitespace(self):
343        for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
344            b = self.type2test(b)
345            self.assertEqual(b.split(), [b])
346        b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
347        self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
348
349    def test_rsplit_string_error(self):
350        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, u' ')
351
352    def test_rsplit_unicodewhitespace(self):
353        b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
354        self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
355
356    def test_partition(self):
357        b = self.type2test(b'mississippi')
358        self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi'))
359        self.assertEqual(b.partition(b'w'), (b'mississippi', b'', b''))
360
361    def test_rpartition(self):
362        b = self.type2test(b'mississippi')
363        self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi'))
364        self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
365        self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
366
367    def test_pickling(self):
368        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
369            for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
370                b = self.type2test(b)
371                ps = pickle.dumps(b, proto)
372                q = pickle.loads(ps)
373                self.assertEqual(b, q)
374
375    def test_strip_bytearray(self):
376        self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b')
377        self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc')
378        self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
379
380    def test_strip_string_error(self):
381        self.assertRaises(TypeError, self.type2test(b'abc').strip, u'b')
382        self.assertRaises(TypeError, self.type2test(b'abc').lstrip, u'b')
383        self.assertRaises(TypeError, self.type2test(b'abc').rstrip, u'b')
384
385    def test_ord(self):
386        b = self.type2test(b'\0A\x7f\x80\xff')
387        self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
388                         [0, 65, 127, 128, 255])
389
390    def test_none_arguments(self):
391        # issue 11828
392        b = self.type2test(b'hello')
393        l = self.type2test(b'l')
394        h = self.type2test(b'h')
395        x = self.type2test(b'x')
396        o = self.type2test(b'o')
397
398        self.assertEqual(2, b.find(l, None))
399        self.assertEqual(3, b.find(l, -2, None))
400        self.assertEqual(2, b.find(l, None, -2))
401        self.assertEqual(0, b.find(h, None, None))
402
403        self.assertEqual(3, b.rfind(l, None))
404        self.assertEqual(3, b.rfind(l, -2, None))
405        self.assertEqual(2, b.rfind(l, None, -2))
406        self.assertEqual(0, b.rfind(h, None, None))
407
408        self.assertEqual(2, b.index(l, None))
409        self.assertEqual(3, b.index(l, -2, None))
410        self.assertEqual(2, b.index(l, None, -2))
411        self.assertEqual(0, b.index(h, None, None))
412
413        self.assertEqual(3, b.rindex(l, None))
414        self.assertEqual(3, b.rindex(l, -2, None))
415        self.assertEqual(2, b.rindex(l, None, -2))
416        self.assertEqual(0, b.rindex(h, None, None))
417
418        self.assertEqual(2, b.count(l, None))
419        self.assertEqual(1, b.count(l, -2, None))
420        self.assertEqual(1, b.count(l, None, -2))
421        self.assertEqual(0, b.count(x, None, None))
422
423        self.assertEqual(True, b.endswith(o, None))
424        self.assertEqual(True, b.endswith(o, -2, None))
425        self.assertEqual(True, b.endswith(l, None, -2))
426        self.assertEqual(False, b.endswith(x, None, None))
427
428        self.assertEqual(True, b.startswith(h, None))
429        self.assertEqual(True, b.startswith(l, -2, None))
430        self.assertEqual(True, b.startswith(h, None, -2))
431        self.assertEqual(False, b.startswith(x, None, None))
432
433    def test_find_etc_raise_correct_error_messages(self):
434        # issue 11828
435        b = self.type2test(b'hello')
436        x = self.type2test(b'x')
437        self.assertRaisesRegexp(TypeError, r'\bfind\b', b.find,
438                                x, None, None, None)
439        self.assertRaisesRegexp(TypeError, r'\brfind\b', b.rfind,
440                                x, None, None, None)
441        self.assertRaisesRegexp(TypeError, r'\bindex\b', b.index,
442                                x, None, None, None)
443        self.assertRaisesRegexp(TypeError, r'\brindex\b', b.rindex,
444                                x, None, None, None)
445        self.assertRaisesRegexp(TypeError, r'\bcount\b', b.count,
446                                x, None, None, None)
447        self.assertRaisesRegexp(TypeError, r'\bstartswith\b', b.startswith,
448                                x, None, None, None)
449        self.assertRaisesRegexp(TypeError, r'\bendswith\b', b.endswith,
450                                x, None, None, None)
451
452    def test_free_after_iterating(self):
453        test.test_support.check_free_after_iterating(self, iter, self.type2test)
454        test.test_support.check_free_after_iterating(self, reversed, self.type2test)
455
456
457class ByteArrayTest(BaseBytesTest):
458    type2test = bytearray
459
460    def test_nohash(self):
461        self.assertRaises(TypeError, hash, bytearray())
462
463    def test_bytearray_api(self):
464        short_sample = b"Hello world\n"
465        sample = short_sample + b"\0"*(20 - len(short_sample))
466        tfn = tempfile.mktemp()
467        try:
468            # Prepare
469            with open(tfn, "wb") as f:
470                f.write(short_sample)
471            # Test readinto
472            with open(tfn, "rb") as f:
473                b = bytearray(20)
474                n = f.readinto(b)
475            self.assertEqual(n, len(short_sample))
476            # Python 2.x
477            b_sample = (ord(s) for s in sample)
478            self.assertEqual(list(b), list(b_sample))
479            # Test writing in binary mode
480            with open(tfn, "wb") as f:
481                f.write(b)
482            with open(tfn, "rb") as f:
483                self.assertEqual(f.read(), sample)
484            # Text mode is ambiguous; don't test
485        finally:
486            try:
487                os.remove(tfn)
488            except os.error:
489                pass
490
491    def test_reverse(self):
492        b = bytearray(b'hello')
493        self.assertEqual(b.reverse(), None)
494        self.assertEqual(b, b'olleh')
495        b = bytearray(b'hello1') # test even number of items
496        b.reverse()
497        self.assertEqual(b, b'1olleh')
498        b = bytearray()
499        b.reverse()
500        self.assertFalse(b)
501
502    def test_regexps(self):
503        def by(s):
504            return bytearray(map(ord, s))
505        b = by("Hello, world")
506        self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")])
507
508    def test_setitem(self):
509        b = bytearray([1, 2, 3])
510        b[1] = 100
511        self.assertEqual(b, bytearray([1, 100, 3]))
512        b[-1] = 200
513        self.assertEqual(b, bytearray([1, 100, 200]))
514        b[0] = Indexable(10)
515        self.assertEqual(b, bytearray([10, 100, 200]))
516        try:
517            b[3] = 0
518            self.fail("Didn't raise IndexError")
519        except IndexError:
520            pass
521        try:
522            b[-10] = 0
523            self.fail("Didn't raise IndexError")
524        except IndexError:
525            pass
526        try:
527            b[0] = 256
528            self.fail("Didn't raise ValueError")
529        except ValueError:
530            pass
531        try:
532            b[0] = Indexable(-1)
533            self.fail("Didn't raise ValueError")
534        except ValueError:
535            pass
536        try:
537            b[0] = None
538            self.fail("Didn't raise TypeError")
539        except TypeError:
540            pass
541
542    def test_delitem(self):
543        b = bytearray(range(10))
544        del b[0]
545        self.assertEqual(b, bytearray(range(1, 10)))
546        del b[-1]
547        self.assertEqual(b, bytearray(range(1, 9)))
548        del b[4]
549        self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
550
551    def test_setslice(self):
552        b = bytearray(range(10))
553        self.assertEqual(list(b), list(range(10)))
554
555        b[0:5] = bytearray([1, 1, 1, 1, 1])
556        self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
557
558        del b[0:-5]
559        self.assertEqual(b, bytearray([5, 6, 7, 8, 9]))
560
561        b[0:0] = bytearray([0, 1, 2, 3, 4])
562        self.assertEqual(b, bytearray(range(10)))
563
564        b[-7:-3] = bytearray([100, 101])
565        self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9]))
566
567        b[3:5] = [3, 4, 5, 6]
568        self.assertEqual(b, bytearray(range(10)))
569
570        b[3:0] = [42, 42, 42]
571        self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
572
573        b[3:] = b'foo'
574        self.assertEqual(b, bytearray([0, 1, 2, 102, 111, 111]))
575
576        b[:3] = memoryview(b'foo')
577        self.assertEqual(b, bytearray([102, 111, 111, 102, 111, 111]))
578
579        b[3:4] = []
580        self.assertEqual(b, bytearray([102, 111, 111, 111, 111]))
581
582        b[1:] = list(b'uuuu')  # this works only on Python2
583        self.assertEqual(b, bytearray([102, 117, 117, 117, 117]))
584
585        for elem in [5, -5, 0, long(10e20), u'str', 2.3, [u'a', u'b'], [[]]]:
586            with self.assertRaises(TypeError):
587                b[3:4] = elem
588
589        for elem in [[254, 255, 256], [-256, 9000]]:
590            with self.assertRaises(ValueError):
591                b[3:4] = elem
592
593    def test_extended_set_del_slice(self):
594        indices = (0, None, 1, 3, 19, 300, 1<<333, -1, -2, -31, -300)
595        for start in indices:
596            for stop in indices:
597                # Skip invalid step 0
598                for step in indices[1:]:
599                    L = list(range(255))
600                    b = bytearray(L)
601                    # Make sure we have a slice of exactly the right length,
602                    # but with different data.
603                    data = L[start:stop:step]
604                    data.reverse()
605                    L[start:stop:step] = data
606                    b[start:stop:step] = data
607                    self.assertEqual(b, bytearray(L))
608
609                    del L[start:stop:step]
610                    del b[start:stop:step]
611                    self.assertEqual(b, bytearray(L))
612
613    def test_setslice_trap(self):
614        # This test verifies that we correctly handle assigning self
615        # to a slice of self (the old Lambert Meertens trap).
616        b = bytearray(range(256))
617        b[8:] = b
618        self.assertEqual(b, bytearray(list(range(8)) + list(range(256))))
619
620    def test_iconcat(self):
621        b = bytearray(b"abc")
622        b1 = b
623        b += b"def"
624        self.assertEqual(b, b"abcdef")
625        self.assertEqual(b, b1)
626        self.assertTrue(b is b1)
627        b += b"xyz"
628        self.assertEqual(b, b"abcdefxyz")
629        try:
630            b += u""
631        except TypeError:
632            pass
633        else:
634            self.fail("bytes += unicode didn't raise TypeError")
635
636    def test_irepeat(self):
637        b = bytearray(b"abc")
638        b1 = b
639        b *= 3
640        self.assertEqual(b, b"abcabcabc")
641        self.assertEqual(b, b1)
642        self.assertTrue(b is b1)
643
644    def test_irepeat_1char(self):
645        b = bytearray(b"x")
646        b1 = b
647        b *= 100
648        self.assertEqual(b, b"x"*100)
649        self.assertEqual(b, b1)
650        self.assertTrue(b is b1)
651
652    def test_alloc(self):
653        b = bytearray()
654        alloc = b.__alloc__()
655        self.assertTrue(alloc >= 0)
656        seq = [alloc]
657        for i in range(100):
658            b += b"x"
659            alloc = b.__alloc__()
660            self.assertGreater(alloc, len(b))  # including trailing null byte
661            if alloc not in seq:
662                seq.append(alloc)
663
664    def test_init_alloc(self):
665        b = bytearray()
666        def g():
667            for i in range(1, 100):
668                yield i
669                a = list(b)
670                self.assertEqual(a, list(range(1, len(a)+1)))
671                self.assertEqual(len(b), len(a))
672                self.assertLessEqual(len(b), i)
673                alloc = b.__alloc__()
674                self.assertGreater(alloc, len(b))  # including trailing null byte
675        b.__init__(g())
676        self.assertEqual(list(b), list(range(1, 100)))
677        self.assertEqual(len(b), 99)
678        alloc = b.__alloc__()
679        self.assertGreater(alloc, len(b))
680
681    def test_extend(self):
682        orig = b'hello'
683        a = bytearray(orig)
684        a.extend(a)
685        self.assertEqual(a, orig + orig)
686        self.assertEqual(a[5:], orig)
687        a = bytearray(b'')
688        # Test iterators that don't have a __length_hint__
689        a.extend(map(ord, orig * 25))
690        a.extend(ord(x) for x in orig * 25)
691        self.assertEqual(a, orig * 50)
692        self.assertEqual(a[-5:], orig)
693        a = bytearray(b'')
694        a.extend(iter(map(ord, orig * 50)))
695        self.assertEqual(a, orig * 50)
696        self.assertEqual(a[-5:], orig)
697        a = bytearray(b'')
698        a.extend(list(map(ord, orig * 50)))
699        self.assertEqual(a, orig * 50)
700        self.assertEqual(a[-5:], orig)
701        a = bytearray(b'')
702        self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
703        self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
704        self.assertEqual(len(a), 0)
705        a = bytearray(b'')
706        a.extend([Indexable(ord('a'))])
707        self.assertEqual(a, b'a')
708
709    def test_remove(self):
710        b = bytearray(b'hello')
711        b.remove(ord('l'))
712        self.assertEqual(b, b'helo')
713        b.remove(ord('l'))
714        self.assertEqual(b, b'heo')
715        self.assertRaises(ValueError, lambda: b.remove(ord('l')))
716        self.assertRaises(ValueError, lambda: b.remove(400))
717        self.assertRaises(TypeError, lambda: b.remove(u'e'))
718        # remove first and last
719        b.remove(ord('o'))
720        b.remove(ord('h'))
721        self.assertEqual(b, b'e')
722        self.assertRaises(TypeError, lambda: b.remove(u'e'))
723        b.remove(Indexable(ord('e')))
724        self.assertEqual(b, b'')
725
726        # test values outside of the ascii range: (0, 127)
727        c = bytearray([126, 127, 128, 129])
728        c.remove(127)
729        self.assertEqual(c, bytearray([126, 128, 129]))
730        c.remove(129)
731        self.assertEqual(c, bytearray([126, 128]))
732
733    def test_pop(self):
734        b = bytearray(b'world')
735        self.assertEqual(b.pop(), ord('d'))
736        self.assertEqual(b.pop(0), ord('w'))
737        self.assertEqual(b.pop(-2), ord('r'))
738        self.assertRaises(IndexError, lambda: b.pop(10))
739        self.assertRaises(IndexError, lambda: bytearray().pop())
740        # test for issue #6846
741        self.assertEqual(bytearray(b'\xff').pop(), 0xff)
742
743    def test_nosort(self):
744        self.assertRaises(AttributeError, lambda: bytearray().sort())
745
746    def test_append(self):
747        b = bytearray(b'hell')
748        b.append(ord('o'))
749        self.assertEqual(b, b'hello')
750        self.assertEqual(b.append(100), None)
751        b = bytearray()
752        b.append(ord('A'))
753        self.assertEqual(len(b), 1)
754        self.assertRaises(TypeError, lambda: b.append(u'o'))
755        b = bytearray()
756        b.append(Indexable(ord('A')))
757        self.assertEqual(b, b'A')
758
759    def test_insert(self):
760        b = bytearray(b'msssspp')
761        b.insert(1, ord('i'))
762        b.insert(4, ord('i'))
763        b.insert(-2, ord('i'))
764        b.insert(1000, ord('i'))
765        self.assertEqual(b, b'mississippi')
766        # allowed in 2.x
767        #self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
768        b = bytearray()
769        b.insert(0, Indexable(ord('A')))
770        self.assertEqual(b, b'A')
771
772    def test_copied(self):
773        # Issue 4348.  Make sure that operations that don't mutate the array
774        # copy the bytes.
775        b = bytearray(b'abc')
776        self.assertFalse(b is b.replace(b'abc', b'cde', 0))
777
778        t = bytearray([i for i in range(256)])
779        x = bytearray(b'')
780        self.assertFalse(x is x.translate(t))
781
782    def test_partition_bytearray_doesnt_share_nullstring(self):
783        a, b, c = bytearray(b"x").partition(b"y")
784        self.assertEqual(b, b"")
785        self.assertEqual(c, b"")
786        self.assertTrue(b is not c)
787        b += b"!"
788        self.assertEqual(c, b"")
789        a, b, c = bytearray(b"x").partition(b"y")
790        self.assertEqual(b, b"")
791        self.assertEqual(c, b"")
792        # Same for rpartition
793        b, c, a = bytearray(b"x").rpartition(b"y")
794        self.assertEqual(b, b"")
795        self.assertEqual(c, b"")
796        self.assertTrue(b is not c)
797        b += b"!"
798        self.assertEqual(c, b"")
799        c, b, a = bytearray(b"x").rpartition(b"y")
800        self.assertEqual(b, b"")
801        self.assertEqual(c, b"")
802
803    def test_resize_forbidden(self):
804        # #4509: can't resize a bytearray when there are buffer exports, even
805        # if it wouldn't reallocate the underlying buffer.
806        # Furthermore, no destructive changes to the buffer may be applied
807        # before raising the error.
808        b = bytearray(range(10))
809        v = memoryview(b)
810        def resize(n):
811            b[1:-1] = range(n + 1, 2*n - 1)
812        resize(10)
813        orig = b[:]
814        self.assertRaises(BufferError, resize, 11)
815        self.assertEqual(b, orig)
816        self.assertRaises(BufferError, resize, 9)
817        self.assertEqual(b, orig)
818        self.assertRaises(BufferError, resize, 0)
819        self.assertEqual(b, orig)
820        # Other operations implying resize
821        self.assertRaises(BufferError, b.pop, 0)
822        self.assertEqual(b, orig)
823        self.assertRaises(BufferError, b.remove, b[1])
824        self.assertEqual(b, orig)
825        def delitem():
826            del b[1]
827        self.assertRaises(BufferError, delitem)
828        self.assertEqual(b, orig)
829        # deleting a non-contiguous slice
830        def delslice():
831            b[1:-1:2] = b""
832        self.assertRaises(BufferError, delslice)
833        self.assertEqual(b, orig)
834
835    def test_empty_bytearray(self):
836        # Issue #7561: operations on empty bytearrays could crash in many
837        # situations, due to a fragile implementation of the
838        # PyByteArray_AS_STRING() C macro.
839        self.assertRaises(ValueError, int, bytearray(b''))
840
841    def test_exhausted_iterator(self):
842        a = self.type2test([1, 2, 3])
843        exhit = iter(a)
844        empit = iter(a)
845        for x in exhit:  # exhaust the iterator
846            next(empit)  # not exhausted
847        a.append(9)
848        self.assertEqual(list(exhit), [])
849        self.assertEqual(list(empit), [9])
850        self.assertEqual(a, self.type2test([1, 2, 3, 9]))
851
852class AssortedBytesTest(unittest.TestCase):
853    #
854    # Test various combinations of bytes and bytearray
855    #
856
857    @check_bytes_warnings
858    def test_repr_str(self):
859        for f in str, repr:
860            self.assertEqual(f(bytearray()), "bytearray(b'')")
861            self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
862            self.assertEqual(f(bytearray([0, 1, 254, 255])),
863                             "bytearray(b'\\x00\\x01\\xfe\\xff')")
864            self.assertEqual(f(b"abc"), "b'abc'")
865            self.assertEqual(f(b"'"), '''b"'"''') # '''
866            self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
867
868    def test_compare_bytes_to_bytearray(self):
869        self.assertEqual(b"abc" == bytes(b"abc"), True)
870        self.assertEqual(b"ab" != bytes(b"abc"), True)
871        self.assertEqual(b"ab" <= bytes(b"abc"), True)
872        self.assertEqual(b"ab" < bytes(b"abc"), True)
873        self.assertEqual(b"abc" >= bytes(b"ab"), True)
874        self.assertEqual(b"abc" > bytes(b"ab"), True)
875
876        self.assertEqual(b"abc" != bytes(b"abc"), False)
877        self.assertEqual(b"ab" == bytes(b"abc"), False)
878        self.assertEqual(b"ab" > bytes(b"abc"), False)
879        self.assertEqual(b"ab" >= bytes(b"abc"), False)
880        self.assertEqual(b"abc" < bytes(b"ab"), False)
881        self.assertEqual(b"abc" <= bytes(b"ab"), False)
882
883        self.assertEqual(bytes(b"abc") == b"abc", True)
884        self.assertEqual(bytes(b"ab") != b"abc", True)
885        self.assertEqual(bytes(b"ab") <= b"abc", True)
886        self.assertEqual(bytes(b"ab") < b"abc", True)
887        self.assertEqual(bytes(b"abc") >= b"ab", True)
888        self.assertEqual(bytes(b"abc") > b"ab", True)
889
890        self.assertEqual(bytes(b"abc") != b"abc", False)
891        self.assertEqual(bytes(b"ab") == b"abc", False)
892        self.assertEqual(bytes(b"ab") > b"abc", False)
893        self.assertEqual(bytes(b"ab") >= b"abc", False)
894        self.assertEqual(bytes(b"abc") < b"ab", False)
895        self.assertEqual(bytes(b"abc") <= b"ab", False)
896
897    @test.test_support.requires_docstrings
898    def test_doc(self):
899        self.assertIsNotNone(bytearray.__doc__)
900        self.assertTrue(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__)
901        self.assertIsNotNone(bytes.__doc__)
902        self.assertTrue(bytes.__doc__.startswith("bytes("), bytes.__doc__)
903
904    def test_from_bytearray(self):
905        sample = bytes(b"Hello world\n\x80\x81\xfe\xff")
906        buf = memoryview(sample)
907        b = bytearray(buf)
908        self.assertEqual(b, bytearray(sample))
909
910    @check_bytes_warnings
911    def test_to_str(self):
912        self.assertEqual(str(b''), "b''")
913        self.assertEqual(str(b'x'), "b'x'")
914        self.assertEqual(str(b'\x80'), "b'\\x80'")
915        self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
916        self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
917        self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
918
919    def test_literal(self):
920        tests =  [
921            (b"Wonderful spam", "Wonderful spam"),
922            (br"Wonderful spam too", "Wonderful spam too"),
923            (b"\xaa\x00\000\200", "\xaa\x00\000\200"),
924            (br"\xaa\x00\000\200", r"\xaa\x00\000\200"),
925        ]
926        for b, s in tests:
927            self.assertEqual(b, bytearray(s, 'latin-1'))
928        for c in range(128, 256):
929            self.assertRaises(SyntaxError, eval,
930                              'b"%s"' % chr(c))
931
932    def test_translate(self):
933        b = b'hello'
934        ba = bytearray(b)
935        rosetta = bytearray(range(0, 256))
936        rosetta[ord('o')] = ord('e')
937        c = b.translate(rosetta, b'l')
938        self.assertEqual(b, b'hello')
939        self.assertEqual(c, b'hee')
940        c = ba.translate(rosetta, b'l')
941        self.assertEqual(ba, b'hello')
942        self.assertEqual(c, b'hee')
943        c = b.translate(None, b'e')
944        self.assertEqual(c, b'hllo')
945        c = ba.translate(None, b'e')
946        self.assertEqual(c, b'hllo')
947        self.assertRaises(TypeError, b.translate, None, None)
948        self.assertRaises(TypeError, ba.translate, None, None)
949
950    def test_split_bytearray(self):
951        self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b'])
952
953    def test_rsplit_bytearray(self):
954        self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b'])
955
956    # Optimizations:
957    # __iter__? (optimization)
958    # __reversed__? (optimization)
959
960    # XXX More string methods?  (Those that don't use character properties)
961
962    # There are tests in string_tests.py that are more
963    # comprehensive for things like partition, etc.
964    # Unfortunately they are all bundled with tests that
965    # are not appropriate for bytes
966
967    # I've started porting some of those into bytearray_tests.py, we should port
968    # the rest that make sense (the code can be cleaned up to use modern
969    # unittest methods at the same time).
970
971class BytearrayPEP3137Test(unittest.TestCase):
972    def marshal(self, x):
973        return bytearray(x)
974
975    def test_returns_new_copy(self):
976        val = self.marshal(b'1234')
977        # On immutable types these MAY return a reference to themselves
978        # but on mutable types like bytearray they MUST return a new copy.
979        for methname in ('zfill', 'rjust', 'ljust', 'center'):
980            method = getattr(val, methname)
981            newval = method(3)
982            self.assertEqual(val, newval)
983            self.assertTrue(val is not newval,
984                            methname+' returned self on a mutable object')
985        for expr in ('val.split()[0]', 'val.rsplit()[0]',
986                     'val.partition(".")[0]', 'val.rpartition(".")[2]',
987                     'val.splitlines()[0]', 'val.replace("", "")'):
988            newval = eval(expr)
989            self.assertEqual(val, newval)
990            self.assertTrue(val is not newval,
991                            expr+' returned val on a mutable object')
992
993
994class ByteArrayAsStringTest(test.string_tests.CommonTest,
995        test.string_tests.NonStringModuleTest):
996    type2test = bytearray
997
998    # Currently the bytes containment testing uses a single integer
999    # value. This may not be the final design, but until then the
1000    # bytes section with in a bytes containment not valid
1001    def test_contains(self):
1002        pass
1003    def test_expandtabs(self):
1004        pass
1005    def test_upper(self):
1006        pass
1007    def test_lower(self):
1008        pass
1009    def test_hash(self):
1010        # XXX check this out
1011        pass
1012
1013
1014class ByteArraySubclass(bytearray):
1015    pass
1016
1017class ByteArraySubclassTest(unittest.TestCase):
1018
1019    def test_basic(self):
1020        self.assertTrue(issubclass(ByteArraySubclass, bytearray))
1021        self.assertIsInstance(ByteArraySubclass(), bytearray)
1022
1023        a, b = b"abcd", b"efgh"
1024        _a, _b = ByteArraySubclass(a), ByteArraySubclass(b)
1025
1026        # test comparison operators with subclass instances
1027        self.assertTrue(_a == _a)
1028        self.assertTrue(_a != _b)
1029        self.assertTrue(_a < _b)
1030        self.assertTrue(_a <= _b)
1031        self.assertTrue(_b >= _a)
1032        self.assertTrue(_b > _a)
1033        self.assertTrue(_a is not a)
1034
1035        # test concat of subclass instances
1036        self.assertEqual(a + b, _a + _b)
1037        self.assertEqual(a + b, a + _b)
1038        self.assertEqual(a + b, _a + b)
1039
1040        # test repeat
1041        self.assertTrue(a*5 == _a*5)
1042
1043    def test_join(self):
1044        # Make sure join returns a NEW object for single item sequences
1045        # involving a subclass.
1046        # Make sure that it is of the appropriate type.
1047        s1 = ByteArraySubclass(b"abcd")
1048        s2 = bytearray().join([s1])
1049        self.assertTrue(s1 is not s2)
1050        self.assertTrue(type(s2) is bytearray, type(s2))
1051
1052        # Test reverse, calling join on subclass
1053        s3 = s1.join([b"abcd"])
1054        self.assertTrue(type(s3) is bytearray)
1055
1056    def test_pickle(self):
1057        a = ByteArraySubclass(b"abcd")
1058        a.x = 10
1059        a.y = ByteArraySubclass(b"efgh")
1060        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1061            b = pickle.loads(pickle.dumps(a, proto))
1062            self.assertNotEqual(id(a), id(b))
1063            self.assertEqual(a, b)
1064            self.assertEqual(a.x, b.x)
1065            self.assertEqual(a.y, b.y)
1066            self.assertEqual(type(a), type(b))
1067            self.assertEqual(type(a.y), type(b.y))
1068
1069    def test_copy(self):
1070        a = ByteArraySubclass(b"abcd")
1071        a.x = 10
1072        a.y = ByteArraySubclass(b"efgh")
1073        for copy_method in (copy.copy, copy.deepcopy):
1074            b = copy_method(a)
1075            self.assertNotEqual(id(a), id(b))
1076            self.assertEqual(a, b)
1077            self.assertEqual(a.x, b.x)
1078            self.assertEqual(a.y, b.y)
1079            self.assertEqual(type(a), type(b))
1080            self.assertEqual(type(a.y), type(b.y))
1081
1082    def test_init_override(self):
1083        class subclass(bytearray):
1084            def __init__(self, newarg=1, *args, **kwargs):
1085                bytearray.__init__(self, *args, **kwargs)
1086        x = subclass(4, source=b"abcd")
1087        self.assertEqual(x, b"abcd")
1088        x = subclass(newarg=4, source=b"abcd")
1089        self.assertEqual(x, b"abcd")
1090
1091def test_main():
1092    #test.test_support.run_unittest(BytesTest)
1093    #test.test_support.run_unittest(AssortedBytesTest)
1094    test.test_support.run_unittest(
1095        ByteArrayTest,
1096        ByteArrayAsStringTest,
1097        ByteArraySubclassTest,
1098        BytearrayPEP3137Test)
1099
1100if __name__ == "__main__":
1101    test_main()
1102