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 array
8import os
9import re
10import sys
11import copy
12import functools
13import pickle
14import tempfile
15import textwrap
16import unittest
17
18import test.support
19from test.support import import_helper
20from test.support import warnings_helper
21import test.string_tests
22import test.list_tests
23from test.support import bigaddrspacetest, MAX_Py_ssize_t
24from test.support.script_helper import assert_python_failure
25
26
27if sys.flags.bytes_warning:
28    def check_bytes_warnings(func):
29        @functools.wraps(func)
30        def wrapper(*args, **kw):
31            with warnings_helper.check_warnings(('', BytesWarning)):
32                return func(*args, **kw)
33        return wrapper
34else:
35    # no-op
36    def check_bytes_warnings(func):
37        return func
38
39
40class Indexable:
41    def __init__(self, value=0):
42        self.value = value
43    def __index__(self):
44        return self.value
45
46
47class BaseBytesTest:
48
49    def test_basics(self):
50        b = self.type2test()
51        self.assertEqual(type(b), self.type2test)
52        self.assertEqual(b.__class__, self.type2test)
53
54    def test_copy(self):
55        a = self.type2test(b"abcd")
56        for copy_method in (copy.copy, copy.deepcopy):
57            b = copy_method(a)
58            self.assertEqual(a, b)
59            self.assertEqual(type(a), type(b))
60
61    def test_empty_sequence(self):
62        b = self.type2test()
63        self.assertEqual(len(b), 0)
64        self.assertRaises(IndexError, lambda: b[0])
65        self.assertRaises(IndexError, lambda: b[1])
66        self.assertRaises(IndexError, lambda: b[sys.maxsize])
67        self.assertRaises(IndexError, lambda: b[sys.maxsize+1])
68        self.assertRaises(IndexError, lambda: b[10**100])
69        self.assertRaises(IndexError, lambda: b[-1])
70        self.assertRaises(IndexError, lambda: b[-2])
71        self.assertRaises(IndexError, lambda: b[-sys.maxsize])
72        self.assertRaises(IndexError, lambda: b[-sys.maxsize-1])
73        self.assertRaises(IndexError, lambda: b[-sys.maxsize-2])
74        self.assertRaises(IndexError, lambda: b[-10**100])
75
76    def test_from_iterable(self):
77        b = self.type2test(range(256))
78        self.assertEqual(len(b), 256)
79        self.assertEqual(list(b), list(range(256)))
80
81        # Non-sequence iterable.
82        b = self.type2test({42})
83        self.assertEqual(b, b"*")
84        b = self.type2test({43, 45})
85        self.assertIn(tuple(b), {(43, 45), (45, 43)})
86
87        # Iterator that has a __length_hint__.
88        b = self.type2test(iter(range(256)))
89        self.assertEqual(len(b), 256)
90        self.assertEqual(list(b), list(range(256)))
91
92        # Iterator that doesn't have a __length_hint__.
93        b = self.type2test(i for i in range(256) if i % 2)
94        self.assertEqual(len(b), 128)
95        self.assertEqual(list(b), list(range(256))[1::2])
96
97        # Sequence without __iter__.
98        class S:
99            def __getitem__(self, i):
100                return (1, 2, 3)[i]
101        b = self.type2test(S())
102        self.assertEqual(b, b"\x01\x02\x03")
103
104    def test_from_tuple(self):
105        # There is a special case for tuples.
106        b = self.type2test(tuple(range(256)))
107        self.assertEqual(len(b), 256)
108        self.assertEqual(list(b), list(range(256)))
109        b = self.type2test((1, 2, 3))
110        self.assertEqual(b, b"\x01\x02\x03")
111
112    def test_from_list(self):
113        # There is a special case for lists.
114        b = self.type2test(list(range(256)))
115        self.assertEqual(len(b), 256)
116        self.assertEqual(list(b), list(range(256)))
117        b = self.type2test([1, 2, 3])
118        self.assertEqual(b, b"\x01\x02\x03")
119
120    def test_from_mutating_list(self):
121        # Issue #34973: Crash in bytes constructor with mutating list.
122        class X:
123            def __index__(self):
124                a.clear()
125                return 42
126        a = [X(), X()]
127        self.assertEqual(bytes(a), b'*')
128
129        class Y:
130            def __index__(self):
131                if len(a) < 1000:
132                    a.append(self)
133                return 42
134        a = [Y()]
135        self.assertEqual(bytes(a), b'*' * 1000)  # should not crash
136
137    def test_from_index(self):
138        b = self.type2test([Indexable(), Indexable(1), Indexable(254),
139                            Indexable(255)])
140        self.assertEqual(list(b), [0, 1, 254, 255])
141        self.assertRaises(ValueError, self.type2test, [Indexable(-1)])
142        self.assertRaises(ValueError, self.type2test, [Indexable(256)])
143
144    def test_from_buffer(self):
145        a = self.type2test(array.array('B', [1, 2, 3]))
146        self.assertEqual(a, b"\x01\x02\x03")
147        a = self.type2test(b"\x01\x02\x03")
148        self.assertEqual(a, b"\x01\x02\x03")
149
150        # Issues #29159 and #34974.
151        # Fallback when __index__ raises a TypeError
152        class B(bytes):
153            def __index__(self):
154                raise TypeError
155
156        self.assertEqual(self.type2test(B(b"foobar")), b"foobar")
157
158    def test_from_ssize(self):
159        self.assertEqual(self.type2test(0), b'')
160        self.assertEqual(self.type2test(1), b'\x00')
161        self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00')
162        self.assertRaises(ValueError, self.type2test, -1)
163
164        self.assertEqual(self.type2test('0', 'ascii'), b'0')
165        self.assertEqual(self.type2test(b'0'), b'0')
166        self.assertRaises(OverflowError, self.type2test, sys.maxsize + 1)
167
168    def test_constructor_type_errors(self):
169        self.assertRaises(TypeError, self.type2test, 0.0)
170        class C:
171            pass
172        self.assertRaises(TypeError, self.type2test, ["0"])
173        self.assertRaises(TypeError, self.type2test, [0.0])
174        self.assertRaises(TypeError, self.type2test, [None])
175        self.assertRaises(TypeError, self.type2test, [C()])
176        self.assertRaises(TypeError, self.type2test, encoding='ascii')
177        self.assertRaises(TypeError, self.type2test, errors='ignore')
178        self.assertRaises(TypeError, self.type2test, 0, 'ascii')
179        self.assertRaises(TypeError, self.type2test, b'', 'ascii')
180        self.assertRaises(TypeError, self.type2test, 0, errors='ignore')
181        self.assertRaises(TypeError, self.type2test, b'', errors='ignore')
182        self.assertRaises(TypeError, self.type2test, '')
183        self.assertRaises(TypeError, self.type2test, '', errors='ignore')
184        self.assertRaises(TypeError, self.type2test, '', b'ascii')
185        self.assertRaises(TypeError, self.type2test, '', 'ascii', b'ignore')
186
187    def test_constructor_value_errors(self):
188        self.assertRaises(ValueError, self.type2test, [-1])
189        self.assertRaises(ValueError, self.type2test, [-sys.maxsize])
190        self.assertRaises(ValueError, self.type2test, [-sys.maxsize-1])
191        self.assertRaises(ValueError, self.type2test, [-sys.maxsize-2])
192        self.assertRaises(ValueError, self.type2test, [-10**100])
193        self.assertRaises(ValueError, self.type2test, [256])
194        self.assertRaises(ValueError, self.type2test, [257])
195        self.assertRaises(ValueError, self.type2test, [sys.maxsize])
196        self.assertRaises(ValueError, self.type2test, [sys.maxsize+1])
197        self.assertRaises(ValueError, self.type2test, [10**100])
198
199    @bigaddrspacetest
200    def test_constructor_overflow(self):
201        size = MAX_Py_ssize_t
202        self.assertRaises((OverflowError, MemoryError), self.type2test, size)
203        try:
204            # Should either pass or raise an error (e.g. on debug builds with
205            # additional malloc() overhead), but shouldn't crash.
206            bytearray(size - 4)
207        except (OverflowError, MemoryError):
208            pass
209
210    def test_constructor_exceptions(self):
211        # Issue #34974: bytes and bytearray constructors replace unexpected
212        # exceptions.
213        class BadInt:
214            def __index__(self):
215                1/0
216        self.assertRaises(ZeroDivisionError, self.type2test, BadInt())
217        self.assertRaises(ZeroDivisionError, self.type2test, [BadInt()])
218
219        class BadIterable:
220            def __iter__(self):
221                1/0
222        self.assertRaises(ZeroDivisionError, self.type2test, BadIterable())
223
224    def test_compare(self):
225        b1 = self.type2test([1, 2, 3])
226        b2 = self.type2test([1, 2, 3])
227        b3 = self.type2test([1, 3])
228
229        self.assertEqual(b1, b2)
230        self.assertTrue(b2 != b3)
231        self.assertTrue(b1 <= b2)
232        self.assertTrue(b1 <= b3)
233        self.assertTrue(b1 <  b3)
234        self.assertTrue(b1 >= b2)
235        self.assertTrue(b3 >= b2)
236        self.assertTrue(b3 >  b2)
237
238        self.assertFalse(b1 != b2)
239        self.assertFalse(b2 == b3)
240        self.assertFalse(b1 >  b2)
241        self.assertFalse(b1 >  b3)
242        self.assertFalse(b1 >= b3)
243        self.assertFalse(b1 <  b2)
244        self.assertFalse(b3 <  b2)
245        self.assertFalse(b3 <= b2)
246
247    @check_bytes_warnings
248    def test_compare_to_str(self):
249        # Byte comparisons with unicode should always fail!
250        # Test this for all expected byte orders and Unicode character
251        # sizes.
252        self.assertEqual(self.type2test(b"\0a\0b\0c") == "abc", False)
253        self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == "abc",
254                            False)
255        self.assertEqual(self.type2test(b"a\0b\0c\0") == "abc", False)
256        self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == "abc",
257                            False)
258        self.assertEqual(self.type2test() == str(), False)
259        self.assertEqual(self.type2test() != str(), True)
260
261    def test_reversed(self):
262        input = list(map(ord, "Hello"))
263        b = self.type2test(input)
264        output = list(reversed(b))
265        input.reverse()
266        self.assertEqual(output, input)
267
268    def test_getslice(self):
269        def by(s):
270            return self.type2test(map(ord, s))
271        b = by("Hello, world")
272
273        self.assertEqual(b[:5], by("Hello"))
274        self.assertEqual(b[1:5], by("ello"))
275        self.assertEqual(b[5:7], by(", "))
276        self.assertEqual(b[7:], by("world"))
277        self.assertEqual(b[7:12], by("world"))
278        self.assertEqual(b[7:100], by("world"))
279
280        self.assertEqual(b[:-7], by("Hello"))
281        self.assertEqual(b[-11:-7], by("ello"))
282        self.assertEqual(b[-7:-5], by(", "))
283        self.assertEqual(b[-5:], by("world"))
284        self.assertEqual(b[-5:12], by("world"))
285        self.assertEqual(b[-5:100], by("world"))
286        self.assertEqual(b[-100:5], by("Hello"))
287
288    def test_extended_getslice(self):
289        # Test extended slicing by comparing with list slicing.
290        L = list(range(255))
291        b = self.type2test(L)
292        indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100)
293        for start in indices:
294            for stop in indices:
295                # Skip step 0 (invalid)
296                for step in indices[1:]:
297                    self.assertEqual(b[start:stop:step], self.type2test(L[start:stop:step]))
298
299    def test_encoding(self):
300        sample = "Hello world\n\u1234\u5678\u9abc"
301        for enc in ("utf-8", "utf-16"):
302            b = self.type2test(sample, enc)
303            self.assertEqual(b, self.type2test(sample.encode(enc)))
304        self.assertRaises(UnicodeEncodeError, self.type2test, sample, "latin-1")
305        b = self.type2test(sample, "latin-1", "ignore")
306        self.assertEqual(b, self.type2test(sample[:-3], "utf-8"))
307
308    def test_decode(self):
309        sample = "Hello world\n\u1234\u5678\u9abc"
310        for enc in ("utf-8", "utf-16"):
311            b = self.type2test(sample, enc)
312            self.assertEqual(b.decode(enc), sample)
313        sample = "Hello world\n\x80\x81\xfe\xff"
314        b = self.type2test(sample, "latin-1")
315        self.assertRaises(UnicodeDecodeError, b.decode, "utf-8")
316        self.assertEqual(b.decode("utf-8", "ignore"), "Hello world\n")
317        self.assertEqual(b.decode(errors="ignore", encoding="utf-8"),
318                         "Hello world\n")
319        # Default encoding is utf-8
320        self.assertEqual(self.type2test(b'\xe2\x98\x83').decode(), '\u2603')
321
322    def test_check_encoding_errors(self):
323        # bpo-37388: bytes(str) and bytes.encode() must check encoding
324        # and errors arguments in dev mode
325        invalid = 'Boom, Shaka Laka, Boom!'
326        encodings = ('ascii', 'utf8', 'latin1')
327        code = textwrap.dedent(f'''
328            import sys
329            type2test = {self.type2test.__name__}
330            encodings = {encodings!r}
331
332            for data in ('', 'short string'):
333                try:
334                    type2test(data, encoding={invalid!r})
335                except LookupError:
336                    pass
337                else:
338                    sys.exit(21)
339
340                for encoding in encodings:
341                    try:
342                        type2test(data, encoding=encoding, errors={invalid!r})
343                    except LookupError:
344                        pass
345                    else:
346                        sys.exit(22)
347
348            for data in (b'', b'short string'):
349                data = type2test(data)
350                print(repr(data))
351                try:
352                    data.decode(encoding={invalid!r})
353                except LookupError:
354                    sys.exit(10)
355                else:
356                    sys.exit(23)
357
358                try:
359                    data.decode(errors={invalid!r})
360                except LookupError:
361                    pass
362                else:
363                    sys.exit(24)
364
365                for encoding in encodings:
366                    try:
367                        data.decode(encoding=encoding, errors={invalid!r})
368                    except LookupError:
369                        pass
370                    else:
371                        sys.exit(25)
372
373            sys.exit(10)
374        ''')
375        proc = assert_python_failure('-X', 'dev', '-c', code)
376        self.assertEqual(proc.rc, 10, proc)
377
378    def test_from_int(self):
379        b = self.type2test(0)
380        self.assertEqual(b, self.type2test())
381        b = self.type2test(10)
382        self.assertEqual(b, self.type2test([0]*10))
383        b = self.type2test(10000)
384        self.assertEqual(b, self.type2test([0]*10000))
385
386    def test_concat(self):
387        b1 = self.type2test(b"abc")
388        b2 = self.type2test(b"def")
389        self.assertEqual(b1 + b2, b"abcdef")
390        self.assertEqual(b1 + bytes(b"def"), b"abcdef")
391        self.assertEqual(bytes(b"def") + b1, b"defabc")
392        self.assertRaises(TypeError, lambda: b1 + "def")
393        self.assertRaises(TypeError, lambda: "abc" + b2)
394
395    def test_repeat(self):
396        for b in b"abc", self.type2test(b"abc"):
397            self.assertEqual(b * 3, b"abcabcabc")
398            self.assertEqual(b * 0, b"")
399            self.assertEqual(b * -1, b"")
400            self.assertRaises(TypeError, lambda: b * 3.14)
401            self.assertRaises(TypeError, lambda: 3.14 * b)
402            # XXX Shouldn't bytes and bytearray agree on what to raise?
403            with self.assertRaises((OverflowError, MemoryError)):
404                c = b * sys.maxsize
405            with self.assertRaises((OverflowError, MemoryError)):
406                b *= sys.maxsize
407
408    def test_repeat_1char(self):
409        self.assertEqual(self.type2test(b'x')*100, self.type2test([ord('x')]*100))
410
411    def test_contains(self):
412        b = self.type2test(b"abc")
413        self.assertIn(ord('a'), b)
414        self.assertIn(int(ord('a')), b)
415        self.assertNotIn(200, b)
416        self.assertRaises(ValueError, lambda: 300 in b)
417        self.assertRaises(ValueError, lambda: -1 in b)
418        self.assertRaises(ValueError, lambda: sys.maxsize+1 in b)
419        self.assertRaises(TypeError, lambda: None in b)
420        self.assertRaises(TypeError, lambda: float(ord('a')) in b)
421        self.assertRaises(TypeError, lambda: "a" in b)
422        for f in bytes, bytearray:
423            self.assertIn(f(b""), b)
424            self.assertIn(f(b"a"), b)
425            self.assertIn(f(b"b"), b)
426            self.assertIn(f(b"c"), b)
427            self.assertIn(f(b"ab"), b)
428            self.assertIn(f(b"bc"), b)
429            self.assertIn(f(b"abc"), b)
430            self.assertNotIn(f(b"ac"), b)
431            self.assertNotIn(f(b"d"), b)
432            self.assertNotIn(f(b"dab"), b)
433            self.assertNotIn(f(b"abd"), b)
434
435    def test_fromhex(self):
436        self.assertRaises(TypeError, self.type2test.fromhex)
437        self.assertRaises(TypeError, self.type2test.fromhex, 1)
438        self.assertEqual(self.type2test.fromhex(''), self.type2test())
439        b = bytearray([0x1a, 0x2b, 0x30])
440        self.assertEqual(self.type2test.fromhex('1a2B30'), b)
441        self.assertEqual(self.type2test.fromhex('  1A 2B  30   '), b)
442
443        # check that ASCII whitespace is ignored
444        self.assertEqual(self.type2test.fromhex(' 1A\n2B\t30\v'), b)
445        for c in "\x09\x0A\x0B\x0C\x0D\x20":
446            self.assertEqual(self.type2test.fromhex(c), self.type2test())
447        for c in "\x1C\x1D\x1E\x1F\x85\xa0\u2000\u2002\u2028":
448            self.assertRaises(ValueError, self.type2test.fromhex, c)
449
450        self.assertEqual(self.type2test.fromhex('0000'), b'\0\0')
451        self.assertRaises(TypeError, self.type2test.fromhex, b'1B')
452        self.assertRaises(ValueError, self.type2test.fromhex, 'a')
453        self.assertRaises(ValueError, self.type2test.fromhex, 'rt')
454        self.assertRaises(ValueError, self.type2test.fromhex, '1a b cd')
455        self.assertRaises(ValueError, self.type2test.fromhex, '\x00')
456        self.assertRaises(ValueError, self.type2test.fromhex, '12   \x00   34')
457
458        for data, pos in (
459            # invalid first hexadecimal character
460            ('12 x4 56', 3),
461            # invalid second hexadecimal character
462            ('12 3x 56', 4),
463            # two invalid hexadecimal characters
464            ('12 xy 56', 3),
465            # test non-ASCII string
466            ('12 3\xff 56', 4),
467        ):
468            with self.assertRaises(ValueError) as cm:
469                self.type2test.fromhex(data)
470            self.assertIn('at position %s' % pos, str(cm.exception))
471
472    def test_hex(self):
473        self.assertRaises(TypeError, self.type2test.hex)
474        self.assertRaises(TypeError, self.type2test.hex, 1)
475        self.assertEqual(self.type2test(b"").hex(), "")
476        self.assertEqual(bytearray([0x1a, 0x2b, 0x30]).hex(), '1a2b30')
477        self.assertEqual(self.type2test(b"\x1a\x2b\x30").hex(), '1a2b30')
478        self.assertEqual(memoryview(b"\x1a\x2b\x30").hex(), '1a2b30')
479
480    def test_hex_separator_basics(self):
481        three_bytes = self.type2test(b'\xb9\x01\xef')
482        self.assertEqual(three_bytes.hex(), 'b901ef')
483        with self.assertRaises(ValueError):
484            three_bytes.hex('')
485        with self.assertRaises(ValueError):
486            three_bytes.hex('xx')
487        self.assertEqual(three_bytes.hex(':', 0), 'b901ef')
488        with self.assertRaises(TypeError):
489            three_bytes.hex(None, 0)
490        with self.assertRaises(ValueError):
491            three_bytes.hex('\xff')
492        with self.assertRaises(ValueError):
493            three_bytes.hex(b'\xff')
494        with self.assertRaises(ValueError):
495            three_bytes.hex(b'\x80')
496        with self.assertRaises(ValueError):
497            three_bytes.hex(chr(0x100))
498        self.assertEqual(three_bytes.hex(':', 0), 'b901ef')
499        self.assertEqual(three_bytes.hex(b'\x00'), 'b9\x0001\x00ef')
500        self.assertEqual(three_bytes.hex('\x00'), 'b9\x0001\x00ef')
501        self.assertEqual(three_bytes.hex(b'\x7f'), 'b9\x7f01\x7fef')
502        self.assertEqual(three_bytes.hex('\x7f'), 'b9\x7f01\x7fef')
503        self.assertEqual(three_bytes.hex(':', 3), 'b901ef')
504        self.assertEqual(three_bytes.hex(':', 4), 'b901ef')
505        self.assertEqual(three_bytes.hex(':', -4), 'b901ef')
506        self.assertEqual(three_bytes.hex(':'), 'b9:01:ef')
507        self.assertEqual(three_bytes.hex(b'$'), 'b9$01$ef')
508        self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef')
509        self.assertEqual(three_bytes.hex(':', -1), 'b9:01:ef')
510        self.assertEqual(three_bytes.hex(':', 2), 'b9:01ef')
511        self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef')
512        self.assertEqual(three_bytes.hex('*', -2), 'b901*ef')
513
514        value = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
515        self.assertEqual(value.hex('.', 8), '7b7305000000776f.726c646902000000.730500000068656c.6c6f690100000030')
516
517    def test_hex_separator_five_bytes(self):
518        five_bytes = self.type2test(range(90,95))
519        self.assertEqual(five_bytes.hex(), '5a5b5c5d5e')
520
521    def test_hex_separator_six_bytes(self):
522        six_bytes = self.type2test(x*3 for x in range(1, 7))
523        self.assertEqual(six_bytes.hex(), '0306090c0f12')
524        self.assertEqual(six_bytes.hex('.', 1), '03.06.09.0c.0f.12')
525        self.assertEqual(six_bytes.hex(' ', 2), '0306 090c 0f12')
526        self.assertEqual(six_bytes.hex('-', 3), '030609-0c0f12')
527        self.assertEqual(six_bytes.hex(':', 4), '0306:090c0f12')
528        self.assertEqual(six_bytes.hex(':', 5), '03:06090c0f12')
529        self.assertEqual(six_bytes.hex(':', 6), '0306090c0f12')
530        self.assertEqual(six_bytes.hex(':', 95), '0306090c0f12')
531        self.assertEqual(six_bytes.hex('_', -3), '030609_0c0f12')
532        self.assertEqual(six_bytes.hex(':', -4), '0306090c:0f12')
533        self.assertEqual(six_bytes.hex(b'@', -5), '0306090c0f@12')
534        self.assertEqual(six_bytes.hex(':', -6), '0306090c0f12')
535        self.assertEqual(six_bytes.hex(' ', -95), '0306090c0f12')
536
537    def test_join(self):
538        self.assertEqual(self.type2test(b"").join([]), b"")
539        self.assertEqual(self.type2test(b"").join([b""]), b"")
540        for lst in [[b"abc"], [b"a", b"bc"], [b"ab", b"c"], [b"a", b"b", b"c"]]:
541            lst = list(map(self.type2test, lst))
542            self.assertEqual(self.type2test(b"").join(lst), b"abc")
543            self.assertEqual(self.type2test(b"").join(tuple(lst)), b"abc")
544            self.assertEqual(self.type2test(b"").join(iter(lst)), b"abc")
545        dot_join = self.type2test(b".:").join
546        self.assertEqual(dot_join([b"ab", b"cd"]), b"ab.:cd")
547        self.assertEqual(dot_join([memoryview(b"ab"), b"cd"]), b"ab.:cd")
548        self.assertEqual(dot_join([b"ab", memoryview(b"cd")]), b"ab.:cd")
549        self.assertEqual(dot_join([bytearray(b"ab"), b"cd"]), b"ab.:cd")
550        self.assertEqual(dot_join([b"ab", bytearray(b"cd")]), b"ab.:cd")
551        # Stress it with many items
552        seq = [b"abc"] * 100000
553        expected = b"abc" + b".:abc" * 99999
554        self.assertEqual(dot_join(seq), expected)
555        # Stress test with empty separator
556        seq = [b"abc"] * 100000
557        expected = b"abc" * 100000
558        self.assertEqual(self.type2test(b"").join(seq), expected)
559        self.assertRaises(TypeError, self.type2test(b" ").join, None)
560        # Error handling and cleanup when some item in the middle of the
561        # sequence has the wrong type.
562        with self.assertRaises(TypeError):
563            dot_join([bytearray(b"ab"), "cd", b"ef"])
564        with self.assertRaises(TypeError):
565            dot_join([memoryview(b"ab"), "cd", b"ef"])
566
567    def test_count(self):
568        b = self.type2test(b'mississippi')
569        i = 105
570        p = 112
571        w = 119
572
573        self.assertEqual(b.count(b'i'), 4)
574        self.assertEqual(b.count(b'ss'), 2)
575        self.assertEqual(b.count(b'w'), 0)
576
577        self.assertEqual(b.count(i), 4)
578        self.assertEqual(b.count(w), 0)
579
580        self.assertEqual(b.count(b'i', 6), 2)
581        self.assertEqual(b.count(b'p', 6), 2)
582        self.assertEqual(b.count(b'i', 1, 3), 1)
583        self.assertEqual(b.count(b'p', 7, 9), 1)
584
585        self.assertEqual(b.count(i, 6), 2)
586        self.assertEqual(b.count(p, 6), 2)
587        self.assertEqual(b.count(i, 1, 3), 1)
588        self.assertEqual(b.count(p, 7, 9), 1)
589
590    def test_startswith(self):
591        b = self.type2test(b'hello')
592        self.assertFalse(self.type2test().startswith(b"anything"))
593        self.assertTrue(b.startswith(b"hello"))
594        self.assertTrue(b.startswith(b"hel"))
595        self.assertTrue(b.startswith(b"h"))
596        self.assertFalse(b.startswith(b"hellow"))
597        self.assertFalse(b.startswith(b"ha"))
598        with self.assertRaises(TypeError) as cm:
599            b.startswith([b'h'])
600        exc = str(cm.exception)
601        self.assertIn('bytes', exc)
602        self.assertIn('tuple', exc)
603
604    def test_endswith(self):
605        b = self.type2test(b'hello')
606        self.assertFalse(bytearray().endswith(b"anything"))
607        self.assertTrue(b.endswith(b"hello"))
608        self.assertTrue(b.endswith(b"llo"))
609        self.assertTrue(b.endswith(b"o"))
610        self.assertFalse(b.endswith(b"whello"))
611        self.assertFalse(b.endswith(b"no"))
612        with self.assertRaises(TypeError) as cm:
613            b.endswith([b'o'])
614        exc = str(cm.exception)
615        self.assertIn('bytes', exc)
616        self.assertIn('tuple', exc)
617
618    def test_find(self):
619        b = self.type2test(b'mississippi')
620        i = 105
621        w = 119
622
623        self.assertEqual(b.find(b'ss'), 2)
624        self.assertEqual(b.find(b'w'), -1)
625        self.assertEqual(b.find(b'mississippian'), -1)
626
627        self.assertEqual(b.find(i), 1)
628        self.assertEqual(b.find(w), -1)
629
630        self.assertEqual(b.find(b'ss', 3), 5)
631        self.assertEqual(b.find(b'ss', 1, 7), 2)
632        self.assertEqual(b.find(b'ss', 1, 3), -1)
633
634        self.assertEqual(b.find(i, 6), 7)
635        self.assertEqual(b.find(i, 1, 3), 1)
636        self.assertEqual(b.find(w, 1, 3), -1)
637
638        for index in (-1, 256, sys.maxsize + 1):
639            self.assertRaisesRegex(
640                ValueError, r'byte must be in range\(0, 256\)',
641                b.find, index)
642
643    def test_rfind(self):
644        b = self.type2test(b'mississippi')
645        i = 105
646        w = 119
647
648        self.assertEqual(b.rfind(b'ss'), 5)
649        self.assertEqual(b.rfind(b'w'), -1)
650        self.assertEqual(b.rfind(b'mississippian'), -1)
651
652        self.assertEqual(b.rfind(i), 10)
653        self.assertEqual(b.rfind(w), -1)
654
655        self.assertEqual(b.rfind(b'ss', 3), 5)
656        self.assertEqual(b.rfind(b'ss', 0, 6), 2)
657
658        self.assertEqual(b.rfind(i, 1, 3), 1)
659        self.assertEqual(b.rfind(i, 3, 9), 7)
660        self.assertEqual(b.rfind(w, 1, 3), -1)
661
662    def test_index(self):
663        b = self.type2test(b'mississippi')
664        i = 105
665        w = 119
666
667        self.assertEqual(b.index(b'ss'), 2)
668        self.assertRaises(ValueError, b.index, b'w')
669        self.assertRaises(ValueError, b.index, b'mississippian')
670
671        self.assertEqual(b.index(i), 1)
672        self.assertRaises(ValueError, b.index, w)
673
674        self.assertEqual(b.index(b'ss', 3), 5)
675        self.assertEqual(b.index(b'ss', 1, 7), 2)
676        self.assertRaises(ValueError, b.index, b'ss', 1, 3)
677
678        self.assertEqual(b.index(i, 6), 7)
679        self.assertEqual(b.index(i, 1, 3), 1)
680        self.assertRaises(ValueError, b.index, w, 1, 3)
681
682    def test_rindex(self):
683        b = self.type2test(b'mississippi')
684        i = 105
685        w = 119
686
687        self.assertEqual(b.rindex(b'ss'), 5)
688        self.assertRaises(ValueError, b.rindex, b'w')
689        self.assertRaises(ValueError, b.rindex, b'mississippian')
690
691        self.assertEqual(b.rindex(i), 10)
692        self.assertRaises(ValueError, b.rindex, w)
693
694        self.assertEqual(b.rindex(b'ss', 3), 5)
695        self.assertEqual(b.rindex(b'ss', 0, 6), 2)
696
697        self.assertEqual(b.rindex(i, 1, 3), 1)
698        self.assertEqual(b.rindex(i, 3, 9), 7)
699        self.assertRaises(ValueError, b.rindex, w, 1, 3)
700
701    def test_mod(self):
702        b = self.type2test(b'hello, %b!')
703        orig = b
704        b = b % b'world'
705        self.assertEqual(b, b'hello, world!')
706        self.assertEqual(orig, b'hello, %b!')
707        self.assertFalse(b is orig)
708        b = self.type2test(b'%s / 100 = %d%%')
709        a = b % (b'seventy-nine', 79)
710        self.assertEqual(a, b'seventy-nine / 100 = 79%')
711        self.assertIs(type(a), self.type2test)
712        # issue 29714
713        b = self.type2test(b'hello,\x00%b!')
714        b = b % b'world'
715        self.assertEqual(b, b'hello,\x00world!')
716        self.assertIs(type(b), self.type2test)
717
718    def test_imod(self):
719        b = self.type2test(b'hello, %b!')
720        orig = b
721        b %= b'world'
722        self.assertEqual(b, b'hello, world!')
723        self.assertEqual(orig, b'hello, %b!')
724        self.assertFalse(b is orig)
725        b = self.type2test(b'%s / 100 = %d%%')
726        b %= (b'seventy-nine', 79)
727        self.assertEqual(b, b'seventy-nine / 100 = 79%')
728        self.assertIs(type(b), self.type2test)
729        # issue 29714
730        b = self.type2test(b'hello,\x00%b!')
731        b %= b'world'
732        self.assertEqual(b, b'hello,\x00world!')
733        self.assertIs(type(b), self.type2test)
734
735    def test_rmod(self):
736        with self.assertRaises(TypeError):
737            object() % self.type2test(b'abc')
738        self.assertIs(self.type2test(b'abc').__rmod__('%r'), NotImplemented)
739
740    def test_replace(self):
741        b = self.type2test(b'mississippi')
742        self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
743        self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
744
745    def test_replace_int_error(self):
746        self.assertRaises(TypeError, self.type2test(b'a b').replace, 32, b'')
747
748    def test_split_string_error(self):
749        self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
750        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
751
752    def test_split_int_error(self):
753        self.assertRaises(TypeError, self.type2test(b'a b').split, 32)
754        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, 32)
755
756    def test_split_unicodewhitespace(self):
757        for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
758            b = self.type2test(b)
759            self.assertEqual(b.split(), [b])
760        b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
761        self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
762
763    def test_rsplit_unicodewhitespace(self):
764        b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
765        self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
766
767    def test_partition(self):
768        b = self.type2test(b'mississippi')
769        self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi'))
770        self.assertEqual(b.partition(b'w'), (b'mississippi', b'', b''))
771
772    def test_rpartition(self):
773        b = self.type2test(b'mississippi')
774        self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi'))
775        self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
776        self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
777
778    def test_partition_string_error(self):
779        self.assertRaises(TypeError, self.type2test(b'a b').partition, ' ')
780        self.assertRaises(TypeError, self.type2test(b'a b').rpartition, ' ')
781
782    def test_partition_int_error(self):
783        self.assertRaises(TypeError, self.type2test(b'a b').partition, 32)
784        self.assertRaises(TypeError, self.type2test(b'a b').rpartition, 32)
785
786    def test_pickling(self):
787        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
788            for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
789                b = self.type2test(b)
790                ps = pickle.dumps(b, proto)
791                q = pickle.loads(ps)
792                self.assertEqual(b, q)
793
794    def test_iterator_pickling(self):
795        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
796            for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
797                it = itorg = iter(self.type2test(b))
798                data = list(self.type2test(b))
799                d = pickle.dumps(it, proto)
800                it = pickle.loads(d)
801                self.assertEqual(type(itorg), type(it))
802                self.assertEqual(list(it), data)
803
804                it = pickle.loads(d)
805                if not b:
806                    continue
807                next(it)
808                d = pickle.dumps(it, proto)
809                it = pickle.loads(d)
810                self.assertEqual(list(it), data[1:])
811
812    def test_strip_bytearray(self):
813        self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b')
814        self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc')
815        self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
816
817    def test_strip_string_error(self):
818        self.assertRaises(TypeError, self.type2test(b'abc').strip, 'ac')
819        self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'ac')
820        self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'ac')
821
822    def test_strip_int_error(self):
823        self.assertRaises(TypeError, self.type2test(b' abc ').strip, 32)
824        self.assertRaises(TypeError, self.type2test(b' abc ').lstrip, 32)
825        self.assertRaises(TypeError, self.type2test(b' abc ').rstrip, 32)
826
827    def test_center(self):
828        # Fill character can be either bytes or bytearray (issue 12380)
829        b = self.type2test(b'abc')
830        for fill_type in (bytes, bytearray):
831            self.assertEqual(b.center(7, fill_type(b'-')),
832                             self.type2test(b'--abc--'))
833
834    def test_ljust(self):
835        # Fill character can be either bytes or bytearray (issue 12380)
836        b = self.type2test(b'abc')
837        for fill_type in (bytes, bytearray):
838            self.assertEqual(b.ljust(7, fill_type(b'-')),
839                             self.type2test(b'abc----'))
840
841    def test_rjust(self):
842        # Fill character can be either bytes or bytearray (issue 12380)
843        b = self.type2test(b'abc')
844        for fill_type in (bytes, bytearray):
845            self.assertEqual(b.rjust(7, fill_type(b'-')),
846                             self.type2test(b'----abc'))
847
848    def test_xjust_int_error(self):
849        self.assertRaises(TypeError, self.type2test(b'abc').center, 7, 32)
850        self.assertRaises(TypeError, self.type2test(b'abc').ljust, 7, 32)
851        self.assertRaises(TypeError, self.type2test(b'abc').rjust, 7, 32)
852
853    def test_ord(self):
854        b = self.type2test(b'\0A\x7f\x80\xff')
855        self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
856                         [0, 65, 127, 128, 255])
857
858    def test_maketrans(self):
859        transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
860        self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable)
861        transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374xyz'
862        self.assertEqual(self.type2test.maketrans(b'\375\376\377', b'xyz'), transtable)
863        self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq')
864        self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def')
865
866    def test_none_arguments(self):
867        # issue 11828
868        b = self.type2test(b'hello')
869        l = self.type2test(b'l')
870        h = self.type2test(b'h')
871        x = self.type2test(b'x')
872        o = self.type2test(b'o')
873
874        self.assertEqual(2, b.find(l, None))
875        self.assertEqual(3, b.find(l, -2, None))
876        self.assertEqual(2, b.find(l, None, -2))
877        self.assertEqual(0, b.find(h, None, None))
878
879        self.assertEqual(3, b.rfind(l, None))
880        self.assertEqual(3, b.rfind(l, -2, None))
881        self.assertEqual(2, b.rfind(l, None, -2))
882        self.assertEqual(0, b.rfind(h, None, None))
883
884        self.assertEqual(2, b.index(l, None))
885        self.assertEqual(3, b.index(l, -2, None))
886        self.assertEqual(2, b.index(l, None, -2))
887        self.assertEqual(0, b.index(h, None, None))
888
889        self.assertEqual(3, b.rindex(l, None))
890        self.assertEqual(3, b.rindex(l, -2, None))
891        self.assertEqual(2, b.rindex(l, None, -2))
892        self.assertEqual(0, b.rindex(h, None, None))
893
894        self.assertEqual(2, b.count(l, None))
895        self.assertEqual(1, b.count(l, -2, None))
896        self.assertEqual(1, b.count(l, None, -2))
897        self.assertEqual(0, b.count(x, None, None))
898
899        self.assertEqual(True, b.endswith(o, None))
900        self.assertEqual(True, b.endswith(o, -2, None))
901        self.assertEqual(True, b.endswith(l, None, -2))
902        self.assertEqual(False, b.endswith(x, None, None))
903
904        self.assertEqual(True, b.startswith(h, None))
905        self.assertEqual(True, b.startswith(l, -2, None))
906        self.assertEqual(True, b.startswith(h, None, -2))
907        self.assertEqual(False, b.startswith(x, None, None))
908
909    def test_integer_arguments_out_of_byte_range(self):
910        b = self.type2test(b'hello')
911
912        for method in (b.count, b.find, b.index, b.rfind, b.rindex):
913            self.assertRaises(ValueError, method, -1)
914            self.assertRaises(ValueError, method, 256)
915            self.assertRaises(ValueError, method, 9999)
916
917    def test_find_etc_raise_correct_error_messages(self):
918        # issue 11828
919        b = self.type2test(b'hello')
920        x = self.type2test(b'x')
921        self.assertRaisesRegex(TypeError, r'\bfind\b', b.find,
922                                x, None, None, None)
923        self.assertRaisesRegex(TypeError, r'\brfind\b', b.rfind,
924                                x, None, None, None)
925        self.assertRaisesRegex(TypeError, r'\bindex\b', b.index,
926                                x, None, None, None)
927        self.assertRaisesRegex(TypeError, r'\brindex\b', b.rindex,
928                                x, None, None, None)
929        self.assertRaisesRegex(TypeError, r'\bcount\b', b.count,
930                                x, None, None, None)
931        self.assertRaisesRegex(TypeError, r'\bstartswith\b', b.startswith,
932                                x, None, None, None)
933        self.assertRaisesRegex(TypeError, r'\bendswith\b', b.endswith,
934                                x, None, None, None)
935
936    def test_free_after_iterating(self):
937        test.support.check_free_after_iterating(self, iter, self.type2test)
938        test.support.check_free_after_iterating(self, reversed, self.type2test)
939
940    def test_translate(self):
941        b = self.type2test(b'hello')
942        rosetta = bytearray(range(256))
943        rosetta[ord('o')] = ord('e')
944
945        self.assertRaises(TypeError, b.translate)
946        self.assertRaises(TypeError, b.translate, None, None)
947        self.assertRaises(ValueError, b.translate, bytes(range(255)))
948
949        c = b.translate(rosetta, b'hello')
950        self.assertEqual(b, b'hello')
951        self.assertIsInstance(c, self.type2test)
952
953        c = b.translate(rosetta)
954        d = b.translate(rosetta, b'')
955        self.assertEqual(c, d)
956        self.assertEqual(c, b'helle')
957
958        c = b.translate(rosetta, b'l')
959        self.assertEqual(c, b'hee')
960        c = b.translate(None, b'e')
961        self.assertEqual(c, b'hllo')
962
963        # test delete as a keyword argument
964        c = b.translate(rosetta, delete=b'')
965        self.assertEqual(c, b'helle')
966        c = b.translate(rosetta, delete=b'l')
967        self.assertEqual(c, b'hee')
968        c = b.translate(None, delete=b'e')
969        self.assertEqual(c, b'hllo')
970
971    def test_sq_item(self):
972        _testcapi = import_helper.import_module('_testcapi')
973        obj = self.type2test((42,))
974        with self.assertRaises(IndexError):
975            _testcapi.sequence_getitem(obj, -2)
976        with self.assertRaises(IndexError):
977            _testcapi.sequence_getitem(obj, 1)
978        self.assertEqual(_testcapi.sequence_getitem(obj, 0), 42)
979
980
981class BytesTest(BaseBytesTest, unittest.TestCase):
982    type2test = bytes
983
984    def test__bytes__(self):
985        foo = b'foo\x00bar'
986        self.assertEqual(foo.__bytes__(), foo)
987        self.assertEqual(type(foo.__bytes__()), self.type2test)
988
989        class bytes_subclass(bytes):
990            pass
991
992        bar = bytes_subclass(b'bar\x00foo')
993        self.assertEqual(bar.__bytes__(), bar)
994        self.assertEqual(type(bar.__bytes__()), self.type2test)
995
996    def test_getitem_error(self):
997        b = b'python'
998        msg = "byte indices must be integers or slices"
999        with self.assertRaisesRegex(TypeError, msg):
1000            b['a']
1001
1002    def test_buffer_is_readonly(self):
1003        fd = os.open(__file__, os.O_RDONLY)
1004        with open(fd, "rb", buffering=0) as f:
1005            self.assertRaises(TypeError, f.readinto, b"")
1006
1007    def test_custom(self):
1008        class A:
1009            def __bytes__(self):
1010                return b'abc'
1011        self.assertEqual(bytes(A()), b'abc')
1012        class A: pass
1013        self.assertRaises(TypeError, bytes, A())
1014        class A:
1015            def __bytes__(self):
1016                return None
1017        self.assertRaises(TypeError, bytes, A())
1018        class A:
1019            def __bytes__(self):
1020                return b'a'
1021            def __index__(self):
1022                return 42
1023        self.assertEqual(bytes(A()), b'a')
1024        # Issue #25766
1025        class A(str):
1026            def __bytes__(self):
1027                return b'abc'
1028        self.assertEqual(bytes(A('\u20ac')), b'abc')
1029        self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4')
1030        # Issue #24731
1031        class A:
1032            def __bytes__(self):
1033                return OtherBytesSubclass(b'abc')
1034        self.assertEqual(bytes(A()), b'abc')
1035        self.assertIs(type(bytes(A())), OtherBytesSubclass)
1036        self.assertEqual(BytesSubclass(A()), b'abc')
1037        self.assertIs(type(BytesSubclass(A())), BytesSubclass)
1038
1039    # Test PyBytes_FromFormat()
1040    def test_from_format(self):
1041        ctypes = import_helper.import_module('ctypes')
1042        _testcapi = import_helper.import_module('_testcapi')
1043        from ctypes import pythonapi, py_object
1044        from ctypes import (
1045            c_int, c_uint,
1046            c_long, c_ulong,
1047            c_size_t, c_ssize_t,
1048            c_char_p)
1049
1050        PyBytes_FromFormat = pythonapi.PyBytes_FromFormat
1051        PyBytes_FromFormat.argtypes = (c_char_p,)
1052        PyBytes_FromFormat.restype = py_object
1053
1054        # basic tests
1055        self.assertEqual(PyBytes_FromFormat(b'format'),
1056                         b'format')
1057        self.assertEqual(PyBytes_FromFormat(b'Hello %s !', b'world'),
1058                         b'Hello world !')
1059
1060        # test formatters
1061        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(0)),
1062                         b'c=\0')
1063        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(ord('@'))),
1064                         b'c=@')
1065        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(255)),
1066                         b'c=\xff')
1067        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd',
1068                                            c_int(1), c_long(2),
1069                                            c_size_t(3)),
1070                         b'd=1 ld=2 zd=3')
1071        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd',
1072                                            c_int(-1), c_long(-2),
1073                                            c_size_t(-3)),
1074                         b'd=-1 ld=-2 zd=-3')
1075        self.assertEqual(PyBytes_FromFormat(b'u=%u lu=%lu zu=%zu',
1076                                            c_uint(123), c_ulong(456),
1077                                            c_size_t(789)),
1078                         b'u=123 lu=456 zu=789')
1079        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(123)),
1080                         b'i=123')
1081        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(-123)),
1082                         b'i=-123')
1083        self.assertEqual(PyBytes_FromFormat(b'x=%x', c_int(0xabc)),
1084                         b'x=abc')
1085
1086        sizeof_ptr = ctypes.sizeof(c_char_p)
1087
1088        if os.name == 'nt':
1089            # Windows (MSCRT)
1090            ptr_format = '0x%0{}X'.format(2 * sizeof_ptr)
1091            def ptr_formatter(ptr):
1092                return (ptr_format % ptr)
1093        else:
1094            # UNIX (glibc)
1095            def ptr_formatter(ptr):
1096                return '%#x' % ptr
1097
1098        ptr = 0xabcdef
1099        self.assertEqual(PyBytes_FromFormat(b'ptr=%p', c_char_p(ptr)),
1100                         ('ptr=' + ptr_formatter(ptr)).encode('ascii'))
1101        self.assertEqual(PyBytes_FromFormat(b's=%s', c_char_p(b'cstr')),
1102                         b's=cstr')
1103
1104        # test minimum and maximum integer values
1105        size_max = c_size_t(-1).value
1106        for formatstr, ctypes_type, value, py_formatter in (
1107            (b'%d', c_int, _testcapi.INT_MIN, str),
1108            (b'%d', c_int, _testcapi.INT_MAX, str),
1109            (b'%ld', c_long, _testcapi.LONG_MIN, str),
1110            (b'%ld', c_long, _testcapi.LONG_MAX, str),
1111            (b'%lu', c_ulong, _testcapi.ULONG_MAX, str),
1112            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MIN, str),
1113            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MAX, str),
1114            (b'%zu', c_size_t, size_max, str),
1115            (b'%p', c_char_p, size_max, ptr_formatter),
1116        ):
1117            self.assertEqual(PyBytes_FromFormat(formatstr, ctypes_type(value)),
1118                             py_formatter(value).encode('ascii')),
1119
1120        # width and precision (width is currently ignored)
1121        self.assertEqual(PyBytes_FromFormat(b'%5s', b'a'),
1122                         b'a')
1123        self.assertEqual(PyBytes_FromFormat(b'%.3s', b'abcdef'),
1124                         b'abc')
1125
1126        # '%%' formatter
1127        self.assertEqual(PyBytes_FromFormat(b'%%'),
1128                         b'%')
1129        self.assertEqual(PyBytes_FromFormat(b'[%%]'),
1130                         b'[%]')
1131        self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))),
1132                         b'%_')
1133        self.assertEqual(PyBytes_FromFormat(b'%%s'),
1134                         b'%s')
1135
1136        # Invalid formats and partial formatting
1137        self.assertEqual(PyBytes_FromFormat(b'%'), b'%')
1138        self.assertEqual(PyBytes_FromFormat(b'x=%i y=%', c_int(2), c_int(3)),
1139                         b'x=2 y=%')
1140
1141        # Issue #19969: %c must raise OverflowError for values
1142        # not in the range [0; 255]
1143        self.assertRaises(OverflowError,
1144                          PyBytes_FromFormat, b'%c', c_int(-1))
1145        self.assertRaises(OverflowError,
1146                          PyBytes_FromFormat, b'%c', c_int(256))
1147
1148        # Issue #33817: empty strings
1149        self.assertEqual(PyBytes_FromFormat(b''),
1150                         b'')
1151        self.assertEqual(PyBytes_FromFormat(b'%s', b''),
1152                         b'')
1153
1154    def test_bytes_blocking(self):
1155        class IterationBlocked(list):
1156            __bytes__ = None
1157        i = [0, 1, 2, 3]
1158        self.assertEqual(bytes(i), b'\x00\x01\x02\x03')
1159        self.assertRaises(TypeError, bytes, IterationBlocked(i))
1160
1161        # At least in CPython, because bytes.__new__ and the C API
1162        # PyBytes_FromObject have different fallback rules, integer
1163        # fallback is handled specially, so test separately.
1164        class IntBlocked(int):
1165            __bytes__ = None
1166        self.assertEqual(bytes(3), b'\0\0\0')
1167        self.assertRaises(TypeError, bytes, IntBlocked(3))
1168
1169        # While there is no separately-defined rule for handling bytes
1170        # subclasses differently from other buffer-interface classes,
1171        # an implementation may well special-case them (as CPython 2.x
1172        # str did), so test them separately.
1173        class BytesSubclassBlocked(bytes):
1174            __bytes__ = None
1175        self.assertEqual(bytes(b'ab'), b'ab')
1176        self.assertRaises(TypeError, bytes, BytesSubclassBlocked(b'ab'))
1177
1178        class BufferBlocked(bytearray):
1179            __bytes__ = None
1180        ba, bb = bytearray(b'ab'), BufferBlocked(b'ab')
1181        self.assertEqual(bytes(ba), b'ab')
1182        self.assertRaises(TypeError, bytes, bb)
1183
1184    def test_repeat_id_preserving(self):
1185        a = b'123abc1@'
1186        b = b'456zyx-+'
1187        self.assertEqual(id(a), id(a))
1188        self.assertNotEqual(id(a), id(b))
1189        self.assertNotEqual(id(a), id(a * -4))
1190        self.assertNotEqual(id(a), id(a * 0))
1191        self.assertEqual(id(a), id(a * 1))
1192        self.assertEqual(id(a), id(1 * a))
1193        self.assertNotEqual(id(a), id(a * 2))
1194
1195        class SubBytes(bytes):
1196            pass
1197
1198        s = SubBytes(b'qwerty()')
1199        self.assertEqual(id(s), id(s))
1200        self.assertNotEqual(id(s), id(s * -4))
1201        self.assertNotEqual(id(s), id(s * 0))
1202        self.assertNotEqual(id(s), id(s * 1))
1203        self.assertNotEqual(id(s), id(1 * s))
1204        self.assertNotEqual(id(s), id(s * 2))
1205
1206
1207class ByteArrayTest(BaseBytesTest, unittest.TestCase):
1208    type2test = bytearray
1209
1210    def test_getitem_error(self):
1211        b = bytearray(b'python')
1212        msg = "bytearray indices must be integers or slices"
1213        with self.assertRaisesRegex(TypeError, msg):
1214            b['a']
1215
1216    def test_setitem_error(self):
1217        b = bytearray(b'python')
1218        msg = "bytearray indices must be integers or slices"
1219        with self.assertRaisesRegex(TypeError, msg):
1220            b['a'] = "python"
1221
1222    def test_nohash(self):
1223        self.assertRaises(TypeError, hash, bytearray())
1224
1225    def test_bytearray_api(self):
1226        short_sample = b"Hello world\n"
1227        sample = short_sample + b"\0"*(20 - len(short_sample))
1228        tfn = tempfile.mktemp()
1229        try:
1230            # Prepare
1231            with open(tfn, "wb") as f:
1232                f.write(short_sample)
1233            # Test readinto
1234            with open(tfn, "rb") as f:
1235                b = bytearray(20)
1236                n = f.readinto(b)
1237            self.assertEqual(n, len(short_sample))
1238            self.assertEqual(list(b), list(sample))
1239            # Test writing in binary mode
1240            with open(tfn, "wb") as f:
1241                f.write(b)
1242            with open(tfn, "rb") as f:
1243                self.assertEqual(f.read(), sample)
1244            # Text mode is ambiguous; don't test
1245        finally:
1246            try:
1247                os.remove(tfn)
1248            except OSError:
1249                pass
1250
1251    def test_reverse(self):
1252        b = bytearray(b'hello')
1253        self.assertEqual(b.reverse(), None)
1254        self.assertEqual(b, b'olleh')
1255        b = bytearray(b'hello1') # test even number of items
1256        b.reverse()
1257        self.assertEqual(b, b'1olleh')
1258        b = bytearray()
1259        b.reverse()
1260        self.assertFalse(b)
1261
1262    def test_clear(self):
1263        b = bytearray(b'python')
1264        b.clear()
1265        self.assertEqual(b, b'')
1266
1267        b = bytearray(b'')
1268        b.clear()
1269        self.assertEqual(b, b'')
1270
1271        b = bytearray(b'')
1272        b.append(ord('r'))
1273        b.clear()
1274        b.append(ord('p'))
1275        self.assertEqual(b, b'p')
1276
1277    def test_copy(self):
1278        b = bytearray(b'abc')
1279        bb = b.copy()
1280        self.assertEqual(bb, b'abc')
1281
1282        b = bytearray(b'')
1283        bb = b.copy()
1284        self.assertEqual(bb, b'')
1285
1286        # test that it's indeed a copy and not a reference
1287        b = bytearray(b'abc')
1288        bb = b.copy()
1289        self.assertEqual(b, bb)
1290        self.assertIsNot(b, bb)
1291        bb.append(ord('d'))
1292        self.assertEqual(bb, b'abcd')
1293        self.assertEqual(b, b'abc')
1294
1295    def test_regexps(self):
1296        def by(s):
1297            return bytearray(map(ord, s))
1298        b = by("Hello, world")
1299        self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
1300
1301    def test_setitem(self):
1302        b = bytearray([1, 2, 3])
1303        b[1] = 100
1304        self.assertEqual(b, bytearray([1, 100, 3]))
1305        b[-1] = 200
1306        self.assertEqual(b, bytearray([1, 100, 200]))
1307        b[0] = Indexable(10)
1308        self.assertEqual(b, bytearray([10, 100, 200]))
1309        try:
1310            b[3] = 0
1311            self.fail("Didn't raise IndexError")
1312        except IndexError:
1313            pass
1314        try:
1315            b[-10] = 0
1316            self.fail("Didn't raise IndexError")
1317        except IndexError:
1318            pass
1319        try:
1320            b[0] = 256
1321            self.fail("Didn't raise ValueError")
1322        except ValueError:
1323            pass
1324        try:
1325            b[0] = Indexable(-1)
1326            self.fail("Didn't raise ValueError")
1327        except ValueError:
1328            pass
1329        try:
1330            b[0] = None
1331            self.fail("Didn't raise TypeError")
1332        except TypeError:
1333            pass
1334
1335    def test_delitem(self):
1336        b = bytearray(range(10))
1337        del b[0]
1338        self.assertEqual(b, bytearray(range(1, 10)))
1339        del b[-1]
1340        self.assertEqual(b, bytearray(range(1, 9)))
1341        del b[4]
1342        self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1343
1344    def test_setslice(self):
1345        b = bytearray(range(10))
1346        self.assertEqual(list(b), list(range(10)))
1347
1348        b[0:5] = bytearray([1, 1, 1, 1, 1])
1349        self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
1350
1351        del b[0:-5]
1352        self.assertEqual(b, bytearray([5, 6, 7, 8, 9]))
1353
1354        b[0:0] = bytearray([0, 1, 2, 3, 4])
1355        self.assertEqual(b, bytearray(range(10)))
1356
1357        b[-7:-3] = bytearray([100, 101])
1358        self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9]))
1359
1360        b[3:5] = [3, 4, 5, 6]
1361        self.assertEqual(b, bytearray(range(10)))
1362
1363        b[3:0] = [42, 42, 42]
1364        self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
1365
1366        b[3:] = b'foo'
1367        self.assertEqual(b, bytearray([0, 1, 2, 102, 111, 111]))
1368
1369        b[:3] = memoryview(b'foo')
1370        self.assertEqual(b, bytearray([102, 111, 111, 102, 111, 111]))
1371
1372        b[3:4] = []
1373        self.assertEqual(b, bytearray([102, 111, 111, 111, 111]))
1374
1375        for elem in [5, -5, 0, int(10e20), 'str', 2.3,
1376                     ['a', 'b'], [b'a', b'b'], [[]]]:
1377            with self.assertRaises(TypeError):
1378                b[3:4] = elem
1379
1380        for elem in [[254, 255, 256], [-256, 9000]]:
1381            with self.assertRaises(ValueError):
1382                b[3:4] = elem
1383
1384    def test_setslice_extend(self):
1385        # Exercise the resizing logic (see issue #19087)
1386        b = bytearray(range(100))
1387        self.assertEqual(list(b), list(range(100)))
1388        del b[:10]
1389        self.assertEqual(list(b), list(range(10, 100)))
1390        b.extend(range(100, 110))
1391        self.assertEqual(list(b), list(range(10, 110)))
1392
1393    def test_fifo_overrun(self):
1394        # Test for issue #23985, a buffer overrun when implementing a FIFO
1395        # Build Python in pydebug mode for best results.
1396        b = bytearray(10)
1397        b.pop()        # Defeat expanding buffer off-by-one quirk
1398        del b[:1]      # Advance start pointer without reallocating
1399        b += bytes(2)  # Append exactly the number of deleted bytes
1400        del b          # Free memory buffer, allowing pydebug verification
1401
1402    def test_del_expand(self):
1403        # Reducing the size should not expand the buffer (issue #23985)
1404        b = bytearray(10)
1405        size = sys.getsizeof(b)
1406        del b[:1]
1407        self.assertLessEqual(sys.getsizeof(b), size)
1408
1409    def test_extended_set_del_slice(self):
1410        indices = (0, None, 1, 3, 19, 300, 1<<333, sys.maxsize,
1411            -1, -2, -31, -300)
1412        for start in indices:
1413            for stop in indices:
1414                # Skip invalid step 0
1415                for step in indices[1:]:
1416                    L = list(range(255))
1417                    b = bytearray(L)
1418                    # Make sure we have a slice of exactly the right length,
1419                    # but with different data.
1420                    data = L[start:stop:step]
1421                    data.reverse()
1422                    L[start:stop:step] = data
1423                    b[start:stop:step] = data
1424                    self.assertEqual(b, bytearray(L))
1425
1426                    del L[start:stop:step]
1427                    del b[start:stop:step]
1428                    self.assertEqual(b, bytearray(L))
1429
1430    def test_setslice_trap(self):
1431        # This test verifies that we correctly handle assigning self
1432        # to a slice of self (the old Lambert Meertens trap).
1433        b = bytearray(range(256))
1434        b[8:] = b
1435        self.assertEqual(b, bytearray(list(range(8)) + list(range(256))))
1436
1437    def test_iconcat(self):
1438        b = bytearray(b"abc")
1439        b1 = b
1440        b += b"def"
1441        self.assertEqual(b, b"abcdef")
1442        self.assertEqual(b, b1)
1443        self.assertIs(b, b1)
1444        b += b"xyz"
1445        self.assertEqual(b, b"abcdefxyz")
1446        try:
1447            b += ""
1448        except TypeError:
1449            pass
1450        else:
1451            self.fail("bytes += unicode didn't raise TypeError")
1452
1453    def test_irepeat(self):
1454        b = bytearray(b"abc")
1455        b1 = b
1456        b *= 3
1457        self.assertEqual(b, b"abcabcabc")
1458        self.assertEqual(b, b1)
1459        self.assertIs(b, b1)
1460
1461    def test_irepeat_1char(self):
1462        b = bytearray(b"x")
1463        b1 = b
1464        b *= 100
1465        self.assertEqual(b, b"x"*100)
1466        self.assertEqual(b, b1)
1467        self.assertIs(b, b1)
1468
1469    def test_alloc(self):
1470        b = bytearray()
1471        alloc = b.__alloc__()
1472        self.assertGreaterEqual(alloc, 0)
1473        seq = [alloc]
1474        for i in range(100):
1475            b += b"x"
1476            alloc = b.__alloc__()
1477            self.assertGreater(alloc, len(b))  # including trailing null byte
1478            if alloc not in seq:
1479                seq.append(alloc)
1480
1481    def test_init_alloc(self):
1482        b = bytearray()
1483        def g():
1484            for i in range(1, 100):
1485                yield i
1486                a = list(b)
1487                self.assertEqual(a, list(range(1, len(a)+1)))
1488                self.assertEqual(len(b), len(a))
1489                self.assertLessEqual(len(b), i)
1490                alloc = b.__alloc__()
1491                self.assertGreater(alloc, len(b))  # including trailing null byte
1492        b.__init__(g())
1493        self.assertEqual(list(b), list(range(1, 100)))
1494        self.assertEqual(len(b), 99)
1495        alloc = b.__alloc__()
1496        self.assertGreater(alloc, len(b))
1497
1498    def test_extend(self):
1499        orig = b'hello'
1500        a = bytearray(orig)
1501        a.extend(a)
1502        self.assertEqual(a, orig + orig)
1503        self.assertEqual(a[5:], orig)
1504        a = bytearray(b'')
1505        # Test iterators that don't have a __length_hint__
1506        a.extend(map(int, orig * 25))
1507        a.extend(int(x) for x in orig * 25)
1508        self.assertEqual(a, orig * 50)
1509        self.assertEqual(a[-5:], orig)
1510        a = bytearray(b'')
1511        a.extend(iter(map(int, orig * 50)))
1512        self.assertEqual(a, orig * 50)
1513        self.assertEqual(a[-5:], orig)
1514        a = bytearray(b'')
1515        a.extend(list(map(int, orig * 50)))
1516        self.assertEqual(a, orig * 50)
1517        self.assertEqual(a[-5:], orig)
1518        a = bytearray(b'')
1519        self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
1520        self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
1521        self.assertEqual(len(a), 0)
1522        a = bytearray(b'')
1523        a.extend([Indexable(ord('a'))])
1524        self.assertEqual(a, b'a')
1525
1526    def test_remove(self):
1527        b = bytearray(b'hello')
1528        b.remove(ord('l'))
1529        self.assertEqual(b, b'helo')
1530        b.remove(ord('l'))
1531        self.assertEqual(b, b'heo')
1532        self.assertRaises(ValueError, lambda: b.remove(ord('l')))
1533        self.assertRaises(ValueError, lambda: b.remove(400))
1534        self.assertRaises(TypeError, lambda: b.remove('e'))
1535        # remove first and last
1536        b.remove(ord('o'))
1537        b.remove(ord('h'))
1538        self.assertEqual(b, b'e')
1539        self.assertRaises(TypeError, lambda: b.remove(b'e'))
1540        b.remove(Indexable(ord('e')))
1541        self.assertEqual(b, b'')
1542
1543        # test values outside of the ascii range: (0, 127)
1544        c = bytearray([126, 127, 128, 129])
1545        c.remove(127)
1546        self.assertEqual(c, bytes([126, 128, 129]))
1547        c.remove(129)
1548        self.assertEqual(c, bytes([126, 128]))
1549
1550    def test_pop(self):
1551        b = bytearray(b'world')
1552        self.assertEqual(b.pop(), ord('d'))
1553        self.assertEqual(b.pop(0), ord('w'))
1554        self.assertEqual(b.pop(-2), ord('r'))
1555        self.assertRaises(IndexError, lambda: b.pop(10))
1556        self.assertRaises(IndexError, lambda: bytearray().pop())
1557        # test for issue #6846
1558        self.assertEqual(bytearray(b'\xff').pop(), 0xff)
1559
1560    def test_nosort(self):
1561        self.assertRaises(AttributeError, lambda: bytearray().sort())
1562
1563    def test_append(self):
1564        b = bytearray(b'hell')
1565        b.append(ord('o'))
1566        self.assertEqual(b, b'hello')
1567        self.assertEqual(b.append(100), None)
1568        b = bytearray()
1569        b.append(ord('A'))
1570        self.assertEqual(len(b), 1)
1571        self.assertRaises(TypeError, lambda: b.append(b'o'))
1572        b = bytearray()
1573        b.append(Indexable(ord('A')))
1574        self.assertEqual(b, b'A')
1575
1576    def test_insert(self):
1577        b = bytearray(b'msssspp')
1578        b.insert(1, ord('i'))
1579        b.insert(4, ord('i'))
1580        b.insert(-2, ord('i'))
1581        b.insert(1000, ord('i'))
1582        self.assertEqual(b, b'mississippi')
1583        self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
1584        b = bytearray()
1585        b.insert(0, Indexable(ord('A')))
1586        self.assertEqual(b, b'A')
1587
1588    def test_copied(self):
1589        # Issue 4348.  Make sure that operations that don't mutate the array
1590        # copy the bytes.
1591        b = bytearray(b'abc')
1592        self.assertIsNot(b, b.replace(b'abc', b'cde', 0))
1593
1594        t = bytearray([i for i in range(256)])
1595        x = bytearray(b'')
1596        self.assertIsNot(x, x.translate(t))
1597
1598    def test_partition_bytearray_doesnt_share_nullstring(self):
1599        a, b, c = bytearray(b"x").partition(b"y")
1600        self.assertEqual(b, b"")
1601        self.assertEqual(c, b"")
1602        self.assertIsNot(b, c)
1603        b += b"!"
1604        self.assertEqual(c, b"")
1605        a, b, c = bytearray(b"x").partition(b"y")
1606        self.assertEqual(b, b"")
1607        self.assertEqual(c, b"")
1608        # Same for rpartition
1609        b, c, a = bytearray(b"x").rpartition(b"y")
1610        self.assertEqual(b, b"")
1611        self.assertEqual(c, b"")
1612        self.assertIsNot(b, c)
1613        b += b"!"
1614        self.assertEqual(c, b"")
1615        c, b, a = bytearray(b"x").rpartition(b"y")
1616        self.assertEqual(b, b"")
1617        self.assertEqual(c, b"")
1618
1619    def test_resize_forbidden(self):
1620        # #4509: can't resize a bytearray when there are buffer exports, even
1621        # if it wouldn't reallocate the underlying buffer.
1622        # Furthermore, no destructive changes to the buffer may be applied
1623        # before raising the error.
1624        b = bytearray(range(10))
1625        v = memoryview(b)
1626        def resize(n):
1627            b[1:-1] = range(n + 1, 2*n - 1)
1628        resize(10)
1629        orig = b[:]
1630        self.assertRaises(BufferError, resize, 11)
1631        self.assertEqual(b, orig)
1632        self.assertRaises(BufferError, resize, 9)
1633        self.assertEqual(b, orig)
1634        self.assertRaises(BufferError, resize, 0)
1635        self.assertEqual(b, orig)
1636        # Other operations implying resize
1637        self.assertRaises(BufferError, b.pop, 0)
1638        self.assertEqual(b, orig)
1639        self.assertRaises(BufferError, b.remove, b[1])
1640        self.assertEqual(b, orig)
1641        def delitem():
1642            del b[1]
1643        self.assertRaises(BufferError, delitem)
1644        self.assertEqual(b, orig)
1645        # deleting a non-contiguous slice
1646        def delslice():
1647            b[1:-1:2] = b""
1648        self.assertRaises(BufferError, delslice)
1649        self.assertEqual(b, orig)
1650
1651    @test.support.cpython_only
1652    def test_obsolete_write_lock(self):
1653        _testcapi = import_helper.import_module('_testcapi')
1654        self.assertRaises(BufferError, _testcapi.getbuffer_with_null_view, bytearray())
1655
1656    def test_iterator_pickling2(self):
1657        orig = bytearray(b'abc')
1658        data = list(b'qwerty')
1659        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1660            # initial iterator
1661            itorig = iter(orig)
1662            d = pickle.dumps((itorig, orig), proto)
1663            it, b = pickle.loads(d)
1664            b[:] = data
1665            self.assertEqual(type(it), type(itorig))
1666            self.assertEqual(list(it), data)
1667
1668            # running iterator
1669            next(itorig)
1670            d = pickle.dumps((itorig, orig), proto)
1671            it, b = pickle.loads(d)
1672            b[:] = data
1673            self.assertEqual(type(it), type(itorig))
1674            self.assertEqual(list(it), data[1:])
1675
1676            # empty iterator
1677            for i in range(1, len(orig)):
1678                next(itorig)
1679            d = pickle.dumps((itorig, orig), proto)
1680            it, b = pickle.loads(d)
1681            b[:] = data
1682            self.assertEqual(type(it), type(itorig))
1683            self.assertEqual(list(it), data[len(orig):])
1684
1685            # exhausted iterator
1686            self.assertRaises(StopIteration, next, itorig)
1687            d = pickle.dumps((itorig, orig), proto)
1688            it, b = pickle.loads(d)
1689            b[:] = data
1690            self.assertEqual(list(it), [])
1691
1692    test_exhausted_iterator = test.list_tests.CommonTest.test_exhausted_iterator
1693
1694    def test_iterator_length_hint(self):
1695        # Issue 27443: __length_hint__ can return negative integer
1696        ba = bytearray(b'ab')
1697        it = iter(ba)
1698        next(it)
1699        ba.clear()
1700        # Shouldn't raise an error
1701        self.assertEqual(list(it), [])
1702
1703    def test_repeat_after_setslice(self):
1704        # bpo-42924: * used to copy from the wrong memory location
1705        b = bytearray(b'abc')
1706        b[:2] = b'x'
1707        b1 = b * 1
1708        b3 = b * 3
1709        self.assertEqual(b1, b'xc')
1710        self.assertEqual(b1, b)
1711        self.assertEqual(b3, b'xcxcxc')
1712
1713
1714class AssortedBytesTest(unittest.TestCase):
1715    #
1716    # Test various combinations of bytes and bytearray
1717    #
1718
1719    @check_bytes_warnings
1720    def test_repr_str(self):
1721        for f in str, repr:
1722            self.assertEqual(f(bytearray()), "bytearray(b'')")
1723            self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
1724            self.assertEqual(f(bytearray([0, 1, 254, 255])),
1725                             "bytearray(b'\\x00\\x01\\xfe\\xff')")
1726            self.assertEqual(f(b"abc"), "b'abc'")
1727            self.assertEqual(f(b"'"), '''b"'"''') # '''
1728            self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
1729
1730    @check_bytes_warnings
1731    def test_format(self):
1732        for b in b'abc', bytearray(b'abc'):
1733            self.assertEqual(format(b), str(b))
1734            self.assertEqual(format(b, ''), str(b))
1735            with self.assertRaisesRegex(TypeError,
1736                                        r'\b%s\b' % re.escape(type(b).__name__)):
1737                format(b, 's')
1738
1739    def test_compare_bytes_to_bytearray(self):
1740        self.assertEqual(b"abc" == bytes(b"abc"), True)
1741        self.assertEqual(b"ab" != bytes(b"abc"), True)
1742        self.assertEqual(b"ab" <= bytes(b"abc"), True)
1743        self.assertEqual(b"ab" < bytes(b"abc"), True)
1744        self.assertEqual(b"abc" >= bytes(b"ab"), True)
1745        self.assertEqual(b"abc" > bytes(b"ab"), True)
1746
1747        self.assertEqual(b"abc" != bytes(b"abc"), False)
1748        self.assertEqual(b"ab" == bytes(b"abc"), False)
1749        self.assertEqual(b"ab" > bytes(b"abc"), False)
1750        self.assertEqual(b"ab" >= bytes(b"abc"), False)
1751        self.assertEqual(b"abc" < bytes(b"ab"), False)
1752        self.assertEqual(b"abc" <= bytes(b"ab"), False)
1753
1754        self.assertEqual(bytes(b"abc") == b"abc", True)
1755        self.assertEqual(bytes(b"ab") != b"abc", True)
1756        self.assertEqual(bytes(b"ab") <= b"abc", True)
1757        self.assertEqual(bytes(b"ab") < b"abc", True)
1758        self.assertEqual(bytes(b"abc") >= b"ab", True)
1759        self.assertEqual(bytes(b"abc") > b"ab", True)
1760
1761        self.assertEqual(bytes(b"abc") != b"abc", False)
1762        self.assertEqual(bytes(b"ab") == b"abc", False)
1763        self.assertEqual(bytes(b"ab") > b"abc", False)
1764        self.assertEqual(bytes(b"ab") >= b"abc", False)
1765        self.assertEqual(bytes(b"abc") < b"ab", False)
1766        self.assertEqual(bytes(b"abc") <= b"ab", False)
1767
1768    @test.support.requires_docstrings
1769    def test_doc(self):
1770        self.assertIsNotNone(bytearray.__doc__)
1771        self.assertTrue(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__)
1772        self.assertIsNotNone(bytes.__doc__)
1773        self.assertTrue(bytes.__doc__.startswith("bytes("), bytes.__doc__)
1774
1775    def test_from_bytearray(self):
1776        sample = bytes(b"Hello world\n\x80\x81\xfe\xff")
1777        buf = memoryview(sample)
1778        b = bytearray(buf)
1779        self.assertEqual(b, bytearray(sample))
1780
1781    @check_bytes_warnings
1782    def test_to_str(self):
1783        self.assertEqual(str(b''), "b''")
1784        self.assertEqual(str(b'x'), "b'x'")
1785        self.assertEqual(str(b'\x80'), "b'\\x80'")
1786        self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
1787        self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
1788        self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
1789
1790    def test_literal(self):
1791        tests =  [
1792            (b"Wonderful spam", "Wonderful spam"),
1793            (br"Wonderful spam too", "Wonderful spam too"),
1794            (b"\xaa\x00\000\200", "\xaa\x00\000\200"),
1795            (br"\xaa\x00\000\200", r"\xaa\x00\000\200"),
1796        ]
1797        for b, s in tests:
1798            self.assertEqual(b, bytearray(s, 'latin-1'))
1799        for c in range(128, 256):
1800            self.assertRaises(SyntaxError, eval,
1801                              'b"%s"' % chr(c))
1802
1803    def test_split_bytearray(self):
1804        self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b'])
1805
1806    def test_rsplit_bytearray(self):
1807        self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b'])
1808
1809    def test_return_self(self):
1810        # bytearray.replace must always return a new bytearray
1811        b = bytearray()
1812        self.assertIsNot(b.replace(b'', b''), b)
1813
1814    @unittest.skipUnless(sys.flags.bytes_warning,
1815                         "BytesWarning is needed for this test: use -bb option")
1816    def test_compare(self):
1817        def bytes_warning():
1818            return warnings_helper.check_warnings(('', BytesWarning))
1819        with bytes_warning():
1820            b'' == ''
1821        with bytes_warning():
1822            '' == b''
1823        with bytes_warning():
1824            b'' != ''
1825        with bytes_warning():
1826            '' != b''
1827        with bytes_warning():
1828            bytearray(b'') == ''
1829        with bytes_warning():
1830            '' == bytearray(b'')
1831        with bytes_warning():
1832            bytearray(b'') != ''
1833        with bytes_warning():
1834            '' != bytearray(b'')
1835        with bytes_warning():
1836            b'\0' == 0
1837        with bytes_warning():
1838            0 == b'\0'
1839        with bytes_warning():
1840            b'\0' != 0
1841        with bytes_warning():
1842            0 != b'\0'
1843
1844    # Optimizations:
1845    # __iter__? (optimization)
1846    # __reversed__? (optimization)
1847
1848    # XXX More string methods?  (Those that don't use character properties)
1849
1850    # There are tests in string_tests.py that are more
1851    # comprehensive for things like partition, etc.
1852    # Unfortunately they are all bundled with tests that
1853    # are not appropriate for bytes
1854
1855    # I've started porting some of those into bytearray_tests.py, we should port
1856    # the rest that make sense (the code can be cleaned up to use modern
1857    # unittest methods at the same time).
1858
1859class BytearrayPEP3137Test(unittest.TestCase):
1860    def marshal(self, x):
1861        return bytearray(x)
1862
1863    def test_returns_new_copy(self):
1864        val = self.marshal(b'1234')
1865        # On immutable types these MAY return a reference to themselves
1866        # but on mutable types like bytearray they MUST return a new copy.
1867        for methname in ('zfill', 'rjust', 'ljust', 'center'):
1868            method = getattr(val, methname)
1869            newval = method(3)
1870            self.assertEqual(val, newval)
1871            self.assertIsNot(val, newval,
1872                            methname+' returned self on a mutable object')
1873        for expr in ('val.split()[0]', 'val.rsplit()[0]',
1874                     'val.partition(b".")[0]', 'val.rpartition(b".")[2]',
1875                     'val.splitlines()[0]', 'val.replace(b"", b"")'):
1876            newval = eval(expr)
1877            self.assertEqual(val, newval)
1878            self.assertIsNot(val, newval,
1879                            expr+' returned val on a mutable object')
1880        sep = self.marshal(b'')
1881        newval = sep.join([val])
1882        self.assertEqual(val, newval)
1883        self.assertIsNot(val, newval)
1884
1885
1886class FixedStringTest(test.string_tests.BaseTest):
1887    def fixtype(self, obj):
1888        if isinstance(obj, str):
1889            return self.type2test(obj.encode("utf-8"))
1890        return super().fixtype(obj)
1891
1892    contains_bytes = True
1893
1894class ByteArrayAsStringTest(FixedStringTest, unittest.TestCase):
1895    type2test = bytearray
1896
1897class BytesAsStringTest(FixedStringTest, unittest.TestCase):
1898    type2test = bytes
1899
1900
1901class SubclassTest:
1902
1903    def test_basic(self):
1904        self.assertTrue(issubclass(self.type2test, self.basetype))
1905        self.assertIsInstance(self.type2test(), self.basetype)
1906
1907        a, b = b"abcd", b"efgh"
1908        _a, _b = self.type2test(a), self.type2test(b)
1909
1910        # test comparison operators with subclass instances
1911        self.assertTrue(_a == _a)
1912        self.assertTrue(_a != _b)
1913        self.assertTrue(_a < _b)
1914        self.assertTrue(_a <= _b)
1915        self.assertTrue(_b >= _a)
1916        self.assertTrue(_b > _a)
1917        self.assertIsNot(_a, a)
1918
1919        # test concat of subclass instances
1920        self.assertEqual(a + b, _a + _b)
1921        self.assertEqual(a + b, a + _b)
1922        self.assertEqual(a + b, _a + b)
1923
1924        # test repeat
1925        self.assertTrue(a*5 == _a*5)
1926
1927    def test_join(self):
1928        # Make sure join returns a NEW object for single item sequences
1929        # involving a subclass.
1930        # Make sure that it is of the appropriate type.
1931        s1 = self.type2test(b"abcd")
1932        s2 = self.basetype().join([s1])
1933        self.assertIsNot(s1, s2)
1934        self.assertIs(type(s2), self.basetype, type(s2))
1935
1936        # Test reverse, calling join on subclass
1937        s3 = s1.join([b"abcd"])
1938        self.assertIs(type(s3), self.basetype)
1939
1940    def test_pickle(self):
1941        a = self.type2test(b"abcd")
1942        a.x = 10
1943        a.y = self.type2test(b"efgh")
1944        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1945            b = pickle.loads(pickle.dumps(a, proto))
1946            self.assertNotEqual(id(a), id(b))
1947            self.assertEqual(a, b)
1948            self.assertEqual(a.x, b.x)
1949            self.assertEqual(a.y, b.y)
1950            self.assertEqual(type(a), type(b))
1951            self.assertEqual(type(a.y), type(b.y))
1952
1953    def test_copy(self):
1954        a = self.type2test(b"abcd")
1955        a.x = 10
1956        a.y = self.type2test(b"efgh")
1957        for copy_method in (copy.copy, copy.deepcopy):
1958            b = copy_method(a)
1959            self.assertNotEqual(id(a), id(b))
1960            self.assertEqual(a, b)
1961            self.assertEqual(a.x, b.x)
1962            self.assertEqual(a.y, b.y)
1963            self.assertEqual(type(a), type(b))
1964            self.assertEqual(type(a.y), type(b.y))
1965
1966    def test_fromhex(self):
1967        b = self.type2test.fromhex('1a2B30')
1968        self.assertEqual(b, b'\x1a\x2b\x30')
1969        self.assertIs(type(b), self.type2test)
1970
1971        class B1(self.basetype):
1972            def __new__(cls, value):
1973                me = self.basetype.__new__(cls, value)
1974                me.foo = 'bar'
1975                return me
1976
1977        b = B1.fromhex('1a2B30')
1978        self.assertEqual(b, b'\x1a\x2b\x30')
1979        self.assertIs(type(b), B1)
1980        self.assertEqual(b.foo, 'bar')
1981
1982        class B2(self.basetype):
1983            def __init__(me, *args, **kwargs):
1984                if self.basetype is not bytes:
1985                    self.basetype.__init__(me, *args, **kwargs)
1986                me.foo = 'bar'
1987
1988        b = B2.fromhex('1a2B30')
1989        self.assertEqual(b, b'\x1a\x2b\x30')
1990        self.assertIs(type(b), B2)
1991        self.assertEqual(b.foo, 'bar')
1992
1993
1994class ByteArraySubclass(bytearray):
1995    pass
1996
1997class BytesSubclass(bytes):
1998    pass
1999
2000class OtherBytesSubclass(bytes):
2001    pass
2002
2003class ByteArraySubclassTest(SubclassTest, unittest.TestCase):
2004    basetype = bytearray
2005    type2test = ByteArraySubclass
2006
2007    def test_init_override(self):
2008        class subclass(bytearray):
2009            def __init__(me, newarg=1, *args, **kwargs):
2010                bytearray.__init__(me, *args, **kwargs)
2011        x = subclass(4, b"abcd")
2012        x = subclass(4, source=b"abcd")
2013        self.assertEqual(x, b"abcd")
2014        x = subclass(newarg=4, source=b"abcd")
2015        self.assertEqual(x, b"abcd")
2016
2017
2018class BytesSubclassTest(SubclassTest, unittest.TestCase):
2019    basetype = bytes
2020    type2test = BytesSubclass
2021
2022
2023if __name__ == "__main__":
2024    unittest.main()
2025