xref: /third_party/python/Lib/test/test_bytes.py (revision 7db96d56)
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 check(fmt, vals, result):
719            b = self.type2test(fmt)
720            b = b % vals
721            self.assertEqual(b, result)
722            self.assertIs(type(b), self.type2test)
723
724        # A set of tests adapted from test_unicode:UnicodeTest.test_formatting
725        check(b'...%(foo)b...', {b'foo':b"abc"}, b'...abc...')
726        check(b'...%(f(o)o)b...', {b'f(o)o':b"abc", b'foo':b'bar'}, b'...abc...')
727        check(b'...%(foo)b...', {b'foo':b"abc",b'def':123}, b'...abc...')
728        check(b'%*b', (5, b'abc',), b'  abc')
729        check(b'%*b', (-5, b'abc',), b'abc  ')
730        check(b'%*.*b', (5, 2, b'abc',), b'   ab')
731        check(b'%*.*b', (5, 3, b'abc',), b'  abc')
732        check(b'%i %*.*b', (10, 5, 3, b'abc',), b'10   abc')
733        check(b'%i%b %*.*b', (10, b'3', 5, 3, b'abc',), b'103   abc')
734        check(b'%c', b'a', b'a')
735
736    def test_imod(self):
737        b = self.type2test(b'hello, %b!')
738        orig = b
739        b %= b'world'
740        self.assertEqual(b, b'hello, world!')
741        self.assertEqual(orig, b'hello, %b!')
742        self.assertFalse(b is orig)
743        b = self.type2test(b'%s / 100 = %d%%')
744        b %= (b'seventy-nine', 79)
745        self.assertEqual(b, b'seventy-nine / 100 = 79%')
746        self.assertIs(type(b), self.type2test)
747        # issue 29714
748        b = self.type2test(b'hello,\x00%b!')
749        b %= b'world'
750        self.assertEqual(b, b'hello,\x00world!')
751        self.assertIs(type(b), self.type2test)
752
753    def test_rmod(self):
754        with self.assertRaises(TypeError):
755            object() % self.type2test(b'abc')
756        self.assertIs(self.type2test(b'abc').__rmod__('%r'), NotImplemented)
757
758    def test_replace(self):
759        b = self.type2test(b'mississippi')
760        self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
761        self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
762
763    def test_replace_int_error(self):
764        self.assertRaises(TypeError, self.type2test(b'a b').replace, 32, b'')
765
766    def test_split_string_error(self):
767        self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
768        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
769
770    def test_split_int_error(self):
771        self.assertRaises(TypeError, self.type2test(b'a b').split, 32)
772        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, 32)
773
774    def test_split_unicodewhitespace(self):
775        for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
776            b = self.type2test(b)
777            self.assertEqual(b.split(), [b])
778        b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
779        self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
780
781    def test_rsplit_unicodewhitespace(self):
782        b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
783        self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
784
785    def test_partition(self):
786        b = self.type2test(b'mississippi')
787        self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi'))
788        self.assertEqual(b.partition(b'w'), (b'mississippi', b'', b''))
789
790    def test_rpartition(self):
791        b = self.type2test(b'mississippi')
792        self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi'))
793        self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
794        self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
795
796    def test_partition_string_error(self):
797        self.assertRaises(TypeError, self.type2test(b'a b').partition, ' ')
798        self.assertRaises(TypeError, self.type2test(b'a b').rpartition, ' ')
799
800    def test_partition_int_error(self):
801        self.assertRaises(TypeError, self.type2test(b'a b').partition, 32)
802        self.assertRaises(TypeError, self.type2test(b'a b').rpartition, 32)
803
804    def test_pickling(self):
805        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
806            for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
807                b = self.type2test(b)
808                ps = pickle.dumps(b, proto)
809                q = pickle.loads(ps)
810                self.assertEqual(b, q)
811
812    def test_iterator_pickling(self):
813        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
814            for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
815                it = itorg = iter(self.type2test(b))
816                data = list(self.type2test(b))
817                d = pickle.dumps(it, proto)
818                it = pickle.loads(d)
819                self.assertEqual(type(itorg), type(it))
820                self.assertEqual(list(it), data)
821
822                it = pickle.loads(d)
823                if not b:
824                    continue
825                next(it)
826                d = pickle.dumps(it, proto)
827                it = pickle.loads(d)
828                self.assertEqual(list(it), data[1:])
829
830    def test_strip_bytearray(self):
831        self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b')
832        self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc')
833        self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
834
835    def test_strip_string_error(self):
836        self.assertRaises(TypeError, self.type2test(b'abc').strip, 'ac')
837        self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'ac')
838        self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'ac')
839
840    def test_strip_int_error(self):
841        self.assertRaises(TypeError, self.type2test(b' abc ').strip, 32)
842        self.assertRaises(TypeError, self.type2test(b' abc ').lstrip, 32)
843        self.assertRaises(TypeError, self.type2test(b' abc ').rstrip, 32)
844
845    def test_center(self):
846        # Fill character can be either bytes or bytearray (issue 12380)
847        b = self.type2test(b'abc')
848        for fill_type in (bytes, bytearray):
849            self.assertEqual(b.center(7, fill_type(b'-')),
850                             self.type2test(b'--abc--'))
851
852    def test_ljust(self):
853        # Fill character can be either bytes or bytearray (issue 12380)
854        b = self.type2test(b'abc')
855        for fill_type in (bytes, bytearray):
856            self.assertEqual(b.ljust(7, fill_type(b'-')),
857                             self.type2test(b'abc----'))
858
859    def test_rjust(self):
860        # Fill character can be either bytes or bytearray (issue 12380)
861        b = self.type2test(b'abc')
862        for fill_type in (bytes, bytearray):
863            self.assertEqual(b.rjust(7, fill_type(b'-')),
864                             self.type2test(b'----abc'))
865
866    def test_xjust_int_error(self):
867        self.assertRaises(TypeError, self.type2test(b'abc').center, 7, 32)
868        self.assertRaises(TypeError, self.type2test(b'abc').ljust, 7, 32)
869        self.assertRaises(TypeError, self.type2test(b'abc').rjust, 7, 32)
870
871    def test_ord(self):
872        b = self.type2test(b'\0A\x7f\x80\xff')
873        self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
874                         [0, 65, 127, 128, 255])
875
876    def test_maketrans(self):
877        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'
878        self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable)
879        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'
880        self.assertEqual(self.type2test.maketrans(b'\375\376\377', b'xyz'), transtable)
881        self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq')
882        self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def')
883
884    def test_none_arguments(self):
885        # issue 11828
886        b = self.type2test(b'hello')
887        l = self.type2test(b'l')
888        h = self.type2test(b'h')
889        x = self.type2test(b'x')
890        o = self.type2test(b'o')
891
892        self.assertEqual(2, b.find(l, None))
893        self.assertEqual(3, b.find(l, -2, None))
894        self.assertEqual(2, b.find(l, None, -2))
895        self.assertEqual(0, b.find(h, None, None))
896
897        self.assertEqual(3, b.rfind(l, None))
898        self.assertEqual(3, b.rfind(l, -2, None))
899        self.assertEqual(2, b.rfind(l, None, -2))
900        self.assertEqual(0, b.rfind(h, None, None))
901
902        self.assertEqual(2, b.index(l, None))
903        self.assertEqual(3, b.index(l, -2, None))
904        self.assertEqual(2, b.index(l, None, -2))
905        self.assertEqual(0, b.index(h, None, None))
906
907        self.assertEqual(3, b.rindex(l, None))
908        self.assertEqual(3, b.rindex(l, -2, None))
909        self.assertEqual(2, b.rindex(l, None, -2))
910        self.assertEqual(0, b.rindex(h, None, None))
911
912        self.assertEqual(2, b.count(l, None))
913        self.assertEqual(1, b.count(l, -2, None))
914        self.assertEqual(1, b.count(l, None, -2))
915        self.assertEqual(0, b.count(x, None, None))
916
917        self.assertEqual(True, b.endswith(o, None))
918        self.assertEqual(True, b.endswith(o, -2, None))
919        self.assertEqual(True, b.endswith(l, None, -2))
920        self.assertEqual(False, b.endswith(x, None, None))
921
922        self.assertEqual(True, b.startswith(h, None))
923        self.assertEqual(True, b.startswith(l, -2, None))
924        self.assertEqual(True, b.startswith(h, None, -2))
925        self.assertEqual(False, b.startswith(x, None, None))
926
927    def test_integer_arguments_out_of_byte_range(self):
928        b = self.type2test(b'hello')
929
930        for method in (b.count, b.find, b.index, b.rfind, b.rindex):
931            self.assertRaises(ValueError, method, -1)
932            self.assertRaises(ValueError, method, 256)
933            self.assertRaises(ValueError, method, 9999)
934
935    def test_find_etc_raise_correct_error_messages(self):
936        # issue 11828
937        b = self.type2test(b'hello')
938        x = self.type2test(b'x')
939        self.assertRaisesRegex(TypeError, r'\bfind\b', b.find,
940                                x, None, None, None)
941        self.assertRaisesRegex(TypeError, r'\brfind\b', b.rfind,
942                                x, None, None, None)
943        self.assertRaisesRegex(TypeError, r'\bindex\b', b.index,
944                                x, None, None, None)
945        self.assertRaisesRegex(TypeError, r'\brindex\b', b.rindex,
946                                x, None, None, None)
947        self.assertRaisesRegex(TypeError, r'\bcount\b', b.count,
948                                x, None, None, None)
949        self.assertRaisesRegex(TypeError, r'\bstartswith\b', b.startswith,
950                                x, None, None, None)
951        self.assertRaisesRegex(TypeError, r'\bendswith\b', b.endswith,
952                                x, None, None, None)
953
954    def test_free_after_iterating(self):
955        test.support.check_free_after_iterating(self, iter, self.type2test)
956        test.support.check_free_after_iterating(self, reversed, self.type2test)
957
958    def test_translate(self):
959        b = self.type2test(b'hello')
960        rosetta = bytearray(range(256))
961        rosetta[ord('o')] = ord('e')
962
963        self.assertRaises(TypeError, b.translate)
964        self.assertRaises(TypeError, b.translate, None, None)
965        self.assertRaises(ValueError, b.translate, bytes(range(255)))
966
967        c = b.translate(rosetta, b'hello')
968        self.assertEqual(b, b'hello')
969        self.assertIsInstance(c, self.type2test)
970
971        c = b.translate(rosetta)
972        d = b.translate(rosetta, b'')
973        self.assertEqual(c, d)
974        self.assertEqual(c, b'helle')
975
976        c = b.translate(rosetta, b'l')
977        self.assertEqual(c, b'hee')
978        c = b.translate(None, b'e')
979        self.assertEqual(c, b'hllo')
980
981        # test delete as a keyword argument
982        c = b.translate(rosetta, delete=b'')
983        self.assertEqual(c, b'helle')
984        c = b.translate(rosetta, delete=b'l')
985        self.assertEqual(c, b'hee')
986        c = b.translate(None, delete=b'e')
987        self.assertEqual(c, b'hllo')
988
989    def test_sq_item(self):
990        _testcapi = import_helper.import_module('_testcapi')
991        obj = self.type2test((42,))
992        with self.assertRaises(IndexError):
993            _testcapi.sequence_getitem(obj, -2)
994        with self.assertRaises(IndexError):
995            _testcapi.sequence_getitem(obj, 1)
996        self.assertEqual(_testcapi.sequence_getitem(obj, 0), 42)
997
998
999class BytesTest(BaseBytesTest, unittest.TestCase):
1000    type2test = bytes
1001
1002    def test__bytes__(self):
1003        foo = b'foo\x00bar'
1004        self.assertEqual(foo.__bytes__(), foo)
1005        self.assertEqual(type(foo.__bytes__()), self.type2test)
1006
1007        class bytes_subclass(bytes):
1008            pass
1009
1010        bar = bytes_subclass(b'bar\x00foo')
1011        self.assertEqual(bar.__bytes__(), bar)
1012        self.assertEqual(type(bar.__bytes__()), self.type2test)
1013
1014    def test_getitem_error(self):
1015        b = b'python'
1016        msg = "byte indices must be integers or slices"
1017        with self.assertRaisesRegex(TypeError, msg):
1018            b['a']
1019
1020    def test_buffer_is_readonly(self):
1021        fd = os.open(__file__, os.O_RDONLY)
1022        with open(fd, "rb", buffering=0) as f:
1023            self.assertRaises(TypeError, f.readinto, b"")
1024
1025    def test_custom(self):
1026        class A:
1027            def __bytes__(self):
1028                return b'abc'
1029        self.assertEqual(bytes(A()), b'abc')
1030        class A: pass
1031        self.assertRaises(TypeError, bytes, A())
1032        class A:
1033            def __bytes__(self):
1034                return None
1035        self.assertRaises(TypeError, bytes, A())
1036        class A:
1037            def __bytes__(self):
1038                return b'a'
1039            def __index__(self):
1040                return 42
1041        self.assertEqual(bytes(A()), b'a')
1042        # Issue #25766
1043        class A(str):
1044            def __bytes__(self):
1045                return b'abc'
1046        self.assertEqual(bytes(A('\u20ac')), b'abc')
1047        self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4')
1048        # Issue #24731
1049        class A:
1050            def __bytes__(self):
1051                return OtherBytesSubclass(b'abc')
1052        self.assertEqual(bytes(A()), b'abc')
1053        self.assertIs(type(bytes(A())), OtherBytesSubclass)
1054        self.assertEqual(BytesSubclass(A()), b'abc')
1055        self.assertIs(type(BytesSubclass(A())), BytesSubclass)
1056
1057    # Test PyBytes_FromFormat()
1058    def test_from_format(self):
1059        ctypes = import_helper.import_module('ctypes')
1060        _testcapi = import_helper.import_module('_testcapi')
1061        from ctypes import pythonapi, py_object
1062        from ctypes import (
1063            c_int, c_uint,
1064            c_long, c_ulong,
1065            c_size_t, c_ssize_t,
1066            c_char_p)
1067
1068        PyBytes_FromFormat = pythonapi.PyBytes_FromFormat
1069        PyBytes_FromFormat.argtypes = (c_char_p,)
1070        PyBytes_FromFormat.restype = py_object
1071
1072        # basic tests
1073        self.assertEqual(PyBytes_FromFormat(b'format'),
1074                         b'format')
1075        self.assertEqual(PyBytes_FromFormat(b'Hello %s !', b'world'),
1076                         b'Hello world !')
1077
1078        # test formatters
1079        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(0)),
1080                         b'c=\0')
1081        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(ord('@'))),
1082                         b'c=@')
1083        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(255)),
1084                         b'c=\xff')
1085        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd',
1086                                            c_int(1), c_long(2),
1087                                            c_size_t(3)),
1088                         b'd=1 ld=2 zd=3')
1089        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd',
1090                                            c_int(-1), c_long(-2),
1091                                            c_size_t(-3)),
1092                         b'd=-1 ld=-2 zd=-3')
1093        self.assertEqual(PyBytes_FromFormat(b'u=%u lu=%lu zu=%zu',
1094                                            c_uint(123), c_ulong(456),
1095                                            c_size_t(789)),
1096                         b'u=123 lu=456 zu=789')
1097        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(123)),
1098                         b'i=123')
1099        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(-123)),
1100                         b'i=-123')
1101        self.assertEqual(PyBytes_FromFormat(b'x=%x', c_int(0xabc)),
1102                         b'x=abc')
1103
1104        sizeof_ptr = ctypes.sizeof(c_char_p)
1105
1106        if os.name == 'nt':
1107            # Windows (MSCRT)
1108            ptr_format = '0x%0{}X'.format(2 * sizeof_ptr)
1109            def ptr_formatter(ptr):
1110                return (ptr_format % ptr)
1111        else:
1112            # UNIX (glibc)
1113            def ptr_formatter(ptr):
1114                return '%#x' % ptr
1115
1116        ptr = 0xabcdef
1117        self.assertEqual(PyBytes_FromFormat(b'ptr=%p', c_char_p(ptr)),
1118                         ('ptr=' + ptr_formatter(ptr)).encode('ascii'))
1119        self.assertEqual(PyBytes_FromFormat(b's=%s', c_char_p(b'cstr')),
1120                         b's=cstr')
1121
1122        # test minimum and maximum integer values
1123        size_max = c_size_t(-1).value
1124        for formatstr, ctypes_type, value, py_formatter in (
1125            (b'%d', c_int, _testcapi.INT_MIN, str),
1126            (b'%d', c_int, _testcapi.INT_MAX, str),
1127            (b'%ld', c_long, _testcapi.LONG_MIN, str),
1128            (b'%ld', c_long, _testcapi.LONG_MAX, str),
1129            (b'%lu', c_ulong, _testcapi.ULONG_MAX, str),
1130            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MIN, str),
1131            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MAX, str),
1132            (b'%zu', c_size_t, size_max, str),
1133            (b'%p', c_char_p, size_max, ptr_formatter),
1134        ):
1135            self.assertEqual(PyBytes_FromFormat(formatstr, ctypes_type(value)),
1136                             py_formatter(value).encode('ascii')),
1137
1138        # width and precision (width is currently ignored)
1139        self.assertEqual(PyBytes_FromFormat(b'%5s', b'a'),
1140                         b'a')
1141        self.assertEqual(PyBytes_FromFormat(b'%.3s', b'abcdef'),
1142                         b'abc')
1143
1144        # '%%' formatter
1145        self.assertEqual(PyBytes_FromFormat(b'%%'),
1146                         b'%')
1147        self.assertEqual(PyBytes_FromFormat(b'[%%]'),
1148                         b'[%]')
1149        self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))),
1150                         b'%_')
1151        self.assertEqual(PyBytes_FromFormat(b'%%s'),
1152                         b'%s')
1153
1154        # Invalid formats and partial formatting
1155        self.assertEqual(PyBytes_FromFormat(b'%'), b'%')
1156        self.assertEqual(PyBytes_FromFormat(b'x=%i y=%', c_int(2), c_int(3)),
1157                         b'x=2 y=%')
1158
1159        # Issue #19969: %c must raise OverflowError for values
1160        # not in the range [0; 255]
1161        self.assertRaises(OverflowError,
1162                          PyBytes_FromFormat, b'%c', c_int(-1))
1163        self.assertRaises(OverflowError,
1164                          PyBytes_FromFormat, b'%c', c_int(256))
1165
1166        # Issue #33817: empty strings
1167        self.assertEqual(PyBytes_FromFormat(b''),
1168                         b'')
1169        self.assertEqual(PyBytes_FromFormat(b'%s', b''),
1170                         b'')
1171
1172    def test_bytes_blocking(self):
1173        class IterationBlocked(list):
1174            __bytes__ = None
1175        i = [0, 1, 2, 3]
1176        self.assertEqual(bytes(i), b'\x00\x01\x02\x03')
1177        self.assertRaises(TypeError, bytes, IterationBlocked(i))
1178
1179        # At least in CPython, because bytes.__new__ and the C API
1180        # PyBytes_FromObject have different fallback rules, integer
1181        # fallback is handled specially, so test separately.
1182        class IntBlocked(int):
1183            __bytes__ = None
1184        self.assertEqual(bytes(3), b'\0\0\0')
1185        self.assertRaises(TypeError, bytes, IntBlocked(3))
1186
1187        # While there is no separately-defined rule for handling bytes
1188        # subclasses differently from other buffer-interface classes,
1189        # an implementation may well special-case them (as CPython 2.x
1190        # str did), so test them separately.
1191        class BytesSubclassBlocked(bytes):
1192            __bytes__ = None
1193        self.assertEqual(bytes(b'ab'), b'ab')
1194        self.assertRaises(TypeError, bytes, BytesSubclassBlocked(b'ab'))
1195
1196        class BufferBlocked(bytearray):
1197            __bytes__ = None
1198        ba, bb = bytearray(b'ab'), BufferBlocked(b'ab')
1199        self.assertEqual(bytes(ba), b'ab')
1200        self.assertRaises(TypeError, bytes, bb)
1201
1202    def test_repeat_id_preserving(self):
1203        a = b'123abc1@'
1204        b = b'456zyx-+'
1205        self.assertEqual(id(a), id(a))
1206        self.assertNotEqual(id(a), id(b))
1207        self.assertNotEqual(id(a), id(a * -4))
1208        self.assertNotEqual(id(a), id(a * 0))
1209        self.assertEqual(id(a), id(a * 1))
1210        self.assertEqual(id(a), id(1 * a))
1211        self.assertNotEqual(id(a), id(a * 2))
1212
1213        class SubBytes(bytes):
1214            pass
1215
1216        s = SubBytes(b'qwerty()')
1217        self.assertEqual(id(s), id(s))
1218        self.assertNotEqual(id(s), id(s * -4))
1219        self.assertNotEqual(id(s), id(s * 0))
1220        self.assertNotEqual(id(s), id(s * 1))
1221        self.assertNotEqual(id(s), id(1 * s))
1222        self.assertNotEqual(id(s), id(s * 2))
1223
1224
1225class ByteArrayTest(BaseBytesTest, unittest.TestCase):
1226    type2test = bytearray
1227
1228    def test_getitem_error(self):
1229        b = bytearray(b'python')
1230        msg = "bytearray indices must be integers or slices"
1231        with self.assertRaisesRegex(TypeError, msg):
1232            b['a']
1233
1234    def test_setitem_error(self):
1235        b = bytearray(b'python')
1236        msg = "bytearray indices must be integers or slices"
1237        with self.assertRaisesRegex(TypeError, msg):
1238            b['a'] = "python"
1239
1240    def test_nohash(self):
1241        self.assertRaises(TypeError, hash, bytearray())
1242
1243    def test_bytearray_api(self):
1244        short_sample = b"Hello world\n"
1245        sample = short_sample + b"\0"*(20 - len(short_sample))
1246        tfn = tempfile.mktemp()
1247        try:
1248            # Prepare
1249            with open(tfn, "wb") as f:
1250                f.write(short_sample)
1251            # Test readinto
1252            with open(tfn, "rb") as f:
1253                b = bytearray(20)
1254                n = f.readinto(b)
1255            self.assertEqual(n, len(short_sample))
1256            self.assertEqual(list(b), list(sample))
1257            # Test writing in binary mode
1258            with open(tfn, "wb") as f:
1259                f.write(b)
1260            with open(tfn, "rb") as f:
1261                self.assertEqual(f.read(), sample)
1262            # Text mode is ambiguous; don't test
1263        finally:
1264            try:
1265                os.remove(tfn)
1266            except OSError:
1267                pass
1268
1269    def test_reverse(self):
1270        b = bytearray(b'hello')
1271        self.assertEqual(b.reverse(), None)
1272        self.assertEqual(b, b'olleh')
1273        b = bytearray(b'hello1') # test even number of items
1274        b.reverse()
1275        self.assertEqual(b, b'1olleh')
1276        b = bytearray()
1277        b.reverse()
1278        self.assertFalse(b)
1279
1280    def test_clear(self):
1281        b = bytearray(b'python')
1282        b.clear()
1283        self.assertEqual(b, b'')
1284
1285        b = bytearray(b'')
1286        b.clear()
1287        self.assertEqual(b, b'')
1288
1289        b = bytearray(b'')
1290        b.append(ord('r'))
1291        b.clear()
1292        b.append(ord('p'))
1293        self.assertEqual(b, b'p')
1294
1295    def test_copy(self):
1296        b = bytearray(b'abc')
1297        bb = b.copy()
1298        self.assertEqual(bb, b'abc')
1299
1300        b = bytearray(b'')
1301        bb = b.copy()
1302        self.assertEqual(bb, b'')
1303
1304        # test that it's indeed a copy and not a reference
1305        b = bytearray(b'abc')
1306        bb = b.copy()
1307        self.assertEqual(b, bb)
1308        self.assertIsNot(b, bb)
1309        bb.append(ord('d'))
1310        self.assertEqual(bb, b'abcd')
1311        self.assertEqual(b, b'abc')
1312
1313    def test_regexps(self):
1314        def by(s):
1315            return bytearray(map(ord, s))
1316        b = by("Hello, world")
1317        self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
1318
1319    def test_setitem(self):
1320        b = bytearray([1, 2, 3])
1321        b[1] = 100
1322        self.assertEqual(b, bytearray([1, 100, 3]))
1323        b[-1] = 200
1324        self.assertEqual(b, bytearray([1, 100, 200]))
1325        b[0] = Indexable(10)
1326        self.assertEqual(b, bytearray([10, 100, 200]))
1327        try:
1328            b[3] = 0
1329            self.fail("Didn't raise IndexError")
1330        except IndexError:
1331            pass
1332        try:
1333            b[-10] = 0
1334            self.fail("Didn't raise IndexError")
1335        except IndexError:
1336            pass
1337        try:
1338            b[0] = 256
1339            self.fail("Didn't raise ValueError")
1340        except ValueError:
1341            pass
1342        try:
1343            b[0] = Indexable(-1)
1344            self.fail("Didn't raise ValueError")
1345        except ValueError:
1346            pass
1347        try:
1348            b[0] = None
1349            self.fail("Didn't raise TypeError")
1350        except TypeError:
1351            pass
1352
1353    def test_delitem(self):
1354        b = bytearray(range(10))
1355        del b[0]
1356        self.assertEqual(b, bytearray(range(1, 10)))
1357        del b[-1]
1358        self.assertEqual(b, bytearray(range(1, 9)))
1359        del b[4]
1360        self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1361
1362    def test_setslice(self):
1363        b = bytearray(range(10))
1364        self.assertEqual(list(b), list(range(10)))
1365
1366        b[0:5] = bytearray([1, 1, 1, 1, 1])
1367        self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
1368
1369        del b[0:-5]
1370        self.assertEqual(b, bytearray([5, 6, 7, 8, 9]))
1371
1372        b[0:0] = bytearray([0, 1, 2, 3, 4])
1373        self.assertEqual(b, bytearray(range(10)))
1374
1375        b[-7:-3] = bytearray([100, 101])
1376        self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9]))
1377
1378        b[3:5] = [3, 4, 5, 6]
1379        self.assertEqual(b, bytearray(range(10)))
1380
1381        b[3:0] = [42, 42, 42]
1382        self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
1383
1384        b[3:] = b'foo'
1385        self.assertEqual(b, bytearray([0, 1, 2, 102, 111, 111]))
1386
1387        b[:3] = memoryview(b'foo')
1388        self.assertEqual(b, bytearray([102, 111, 111, 102, 111, 111]))
1389
1390        b[3:4] = []
1391        self.assertEqual(b, bytearray([102, 111, 111, 111, 111]))
1392
1393        for elem in [5, -5, 0, int(10e20), 'str', 2.3,
1394                     ['a', 'b'], [b'a', b'b'], [[]]]:
1395            with self.assertRaises(TypeError):
1396                b[3:4] = elem
1397
1398        for elem in [[254, 255, 256], [-256, 9000]]:
1399            with self.assertRaises(ValueError):
1400                b[3:4] = elem
1401
1402    def test_setslice_extend(self):
1403        # Exercise the resizing logic (see issue #19087)
1404        b = bytearray(range(100))
1405        self.assertEqual(list(b), list(range(100)))
1406        del b[:10]
1407        self.assertEqual(list(b), list(range(10, 100)))
1408        b.extend(range(100, 110))
1409        self.assertEqual(list(b), list(range(10, 110)))
1410
1411    def test_fifo_overrun(self):
1412        # Test for issue #23985, a buffer overrun when implementing a FIFO
1413        # Build Python in pydebug mode for best results.
1414        b = bytearray(10)
1415        b.pop()        # Defeat expanding buffer off-by-one quirk
1416        del b[:1]      # Advance start pointer without reallocating
1417        b += bytes(2)  # Append exactly the number of deleted bytes
1418        del b          # Free memory buffer, allowing pydebug verification
1419
1420    def test_del_expand(self):
1421        # Reducing the size should not expand the buffer (issue #23985)
1422        b = bytearray(10)
1423        size = sys.getsizeof(b)
1424        del b[:1]
1425        self.assertLessEqual(sys.getsizeof(b), size)
1426
1427    def test_extended_set_del_slice(self):
1428        indices = (0, None, 1, 3, 19, 300, 1<<333, sys.maxsize,
1429            -1, -2, -31, -300)
1430        for start in indices:
1431            for stop in indices:
1432                # Skip invalid step 0
1433                for step in indices[1:]:
1434                    L = list(range(255))
1435                    b = bytearray(L)
1436                    # Make sure we have a slice of exactly the right length,
1437                    # but with different data.
1438                    data = L[start:stop:step]
1439                    data.reverse()
1440                    L[start:stop:step] = data
1441                    b[start:stop:step] = data
1442                    self.assertEqual(b, bytearray(L))
1443
1444                    del L[start:stop:step]
1445                    del b[start:stop:step]
1446                    self.assertEqual(b, bytearray(L))
1447
1448    def test_setslice_trap(self):
1449        # This test verifies that we correctly handle assigning self
1450        # to a slice of self (the old Lambert Meertens trap).
1451        b = bytearray(range(256))
1452        b[8:] = b
1453        self.assertEqual(b, bytearray(list(range(8)) + list(range(256))))
1454
1455    def test_iconcat(self):
1456        b = bytearray(b"abc")
1457        b1 = b
1458        b += b"def"
1459        self.assertEqual(b, b"abcdef")
1460        self.assertEqual(b, b1)
1461        self.assertIs(b, b1)
1462        b += b"xyz"
1463        self.assertEqual(b, b"abcdefxyz")
1464        try:
1465            b += ""
1466        except TypeError:
1467            pass
1468        else:
1469            self.fail("bytes += unicode didn't raise TypeError")
1470
1471    def test_irepeat(self):
1472        b = bytearray(b"abc")
1473        b1 = b
1474        b *= 3
1475        self.assertEqual(b, b"abcabcabc")
1476        self.assertEqual(b, b1)
1477        self.assertIs(b, b1)
1478
1479    def test_irepeat_1char(self):
1480        b = bytearray(b"x")
1481        b1 = b
1482        b *= 100
1483        self.assertEqual(b, b"x"*100)
1484        self.assertEqual(b, b1)
1485        self.assertIs(b, b1)
1486
1487    def test_alloc(self):
1488        b = bytearray()
1489        alloc = b.__alloc__()
1490        self.assertGreaterEqual(alloc, 0)
1491        seq = [alloc]
1492        for i in range(100):
1493            b += b"x"
1494            alloc = b.__alloc__()
1495            self.assertGreater(alloc, len(b))  # including trailing null byte
1496            if alloc not in seq:
1497                seq.append(alloc)
1498
1499    def test_init_alloc(self):
1500        b = bytearray()
1501        def g():
1502            for i in range(1, 100):
1503                yield i
1504                a = list(b)
1505                self.assertEqual(a, list(range(1, len(a)+1)))
1506                self.assertEqual(len(b), len(a))
1507                self.assertLessEqual(len(b), i)
1508                alloc = b.__alloc__()
1509                self.assertGreater(alloc, len(b))  # including trailing null byte
1510        b.__init__(g())
1511        self.assertEqual(list(b), list(range(1, 100)))
1512        self.assertEqual(len(b), 99)
1513        alloc = b.__alloc__()
1514        self.assertGreater(alloc, len(b))
1515
1516    def test_extend(self):
1517        orig = b'hello'
1518        a = bytearray(orig)
1519        a.extend(a)
1520        self.assertEqual(a, orig + orig)
1521        self.assertEqual(a[5:], orig)
1522        a = bytearray(b'')
1523        # Test iterators that don't have a __length_hint__
1524        a.extend(map(int, orig * 25))
1525        a.extend(int(x) for x in orig * 25)
1526        self.assertEqual(a, orig * 50)
1527        self.assertEqual(a[-5:], orig)
1528        a = bytearray(b'')
1529        a.extend(iter(map(int, orig * 50)))
1530        self.assertEqual(a, orig * 50)
1531        self.assertEqual(a[-5:], orig)
1532        a = bytearray(b'')
1533        a.extend(list(map(int, orig * 50)))
1534        self.assertEqual(a, orig * 50)
1535        self.assertEqual(a[-5:], orig)
1536        a = bytearray(b'')
1537        self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
1538        self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
1539        self.assertEqual(len(a), 0)
1540        a = bytearray(b'')
1541        a.extend([Indexable(ord('a'))])
1542        self.assertEqual(a, b'a')
1543
1544    def test_remove(self):
1545        b = bytearray(b'hello')
1546        b.remove(ord('l'))
1547        self.assertEqual(b, b'helo')
1548        b.remove(ord('l'))
1549        self.assertEqual(b, b'heo')
1550        self.assertRaises(ValueError, lambda: b.remove(ord('l')))
1551        self.assertRaises(ValueError, lambda: b.remove(400))
1552        self.assertRaises(TypeError, lambda: b.remove('e'))
1553        # remove first and last
1554        b.remove(ord('o'))
1555        b.remove(ord('h'))
1556        self.assertEqual(b, b'e')
1557        self.assertRaises(TypeError, lambda: b.remove(b'e'))
1558        b.remove(Indexable(ord('e')))
1559        self.assertEqual(b, b'')
1560
1561        # test values outside of the ascii range: (0, 127)
1562        c = bytearray([126, 127, 128, 129])
1563        c.remove(127)
1564        self.assertEqual(c, bytes([126, 128, 129]))
1565        c.remove(129)
1566        self.assertEqual(c, bytes([126, 128]))
1567
1568    def test_pop(self):
1569        b = bytearray(b'world')
1570        self.assertEqual(b.pop(), ord('d'))
1571        self.assertEqual(b.pop(0), ord('w'))
1572        self.assertEqual(b.pop(-2), ord('r'))
1573        self.assertRaises(IndexError, lambda: b.pop(10))
1574        self.assertRaises(IndexError, lambda: bytearray().pop())
1575        # test for issue #6846
1576        self.assertEqual(bytearray(b'\xff').pop(), 0xff)
1577
1578    def test_nosort(self):
1579        self.assertRaises(AttributeError, lambda: bytearray().sort())
1580
1581    def test_append(self):
1582        b = bytearray(b'hell')
1583        b.append(ord('o'))
1584        self.assertEqual(b, b'hello')
1585        self.assertEqual(b.append(100), None)
1586        b = bytearray()
1587        b.append(ord('A'))
1588        self.assertEqual(len(b), 1)
1589        self.assertRaises(TypeError, lambda: b.append(b'o'))
1590        b = bytearray()
1591        b.append(Indexable(ord('A')))
1592        self.assertEqual(b, b'A')
1593
1594    def test_insert(self):
1595        b = bytearray(b'msssspp')
1596        b.insert(1, ord('i'))
1597        b.insert(4, ord('i'))
1598        b.insert(-2, ord('i'))
1599        b.insert(1000, ord('i'))
1600        self.assertEqual(b, b'mississippi')
1601        self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
1602        b = bytearray()
1603        b.insert(0, Indexable(ord('A')))
1604        self.assertEqual(b, b'A')
1605
1606    def test_copied(self):
1607        # Issue 4348.  Make sure that operations that don't mutate the array
1608        # copy the bytes.
1609        b = bytearray(b'abc')
1610        self.assertIsNot(b, b.replace(b'abc', b'cde', 0))
1611
1612        t = bytearray([i for i in range(256)])
1613        x = bytearray(b'')
1614        self.assertIsNot(x, x.translate(t))
1615
1616    def test_partition_bytearray_doesnt_share_nullstring(self):
1617        a, b, c = bytearray(b"x").partition(b"y")
1618        self.assertEqual(b, b"")
1619        self.assertEqual(c, b"")
1620        self.assertIsNot(b, c)
1621        b += b"!"
1622        self.assertEqual(c, b"")
1623        a, b, c = bytearray(b"x").partition(b"y")
1624        self.assertEqual(b, b"")
1625        self.assertEqual(c, b"")
1626        # Same for rpartition
1627        b, c, a = bytearray(b"x").rpartition(b"y")
1628        self.assertEqual(b, b"")
1629        self.assertEqual(c, b"")
1630        self.assertIsNot(b, c)
1631        b += b"!"
1632        self.assertEqual(c, b"")
1633        c, b, a = bytearray(b"x").rpartition(b"y")
1634        self.assertEqual(b, b"")
1635        self.assertEqual(c, b"")
1636
1637    def test_resize_forbidden(self):
1638        # #4509: can't resize a bytearray when there are buffer exports, even
1639        # if it wouldn't reallocate the underlying buffer.
1640        # Furthermore, no destructive changes to the buffer may be applied
1641        # before raising the error.
1642        b = bytearray(range(10))
1643        v = memoryview(b)
1644        def resize(n):
1645            b[1:-1] = range(n + 1, 2*n - 1)
1646        resize(10)
1647        orig = b[:]
1648        self.assertRaises(BufferError, resize, 11)
1649        self.assertEqual(b, orig)
1650        self.assertRaises(BufferError, resize, 9)
1651        self.assertEqual(b, orig)
1652        self.assertRaises(BufferError, resize, 0)
1653        self.assertEqual(b, orig)
1654        # Other operations implying resize
1655        self.assertRaises(BufferError, b.pop, 0)
1656        self.assertEqual(b, orig)
1657        self.assertRaises(BufferError, b.remove, b[1])
1658        self.assertEqual(b, orig)
1659        def delitem():
1660            del b[1]
1661        self.assertRaises(BufferError, delitem)
1662        self.assertEqual(b, orig)
1663        # deleting a non-contiguous slice
1664        def delslice():
1665            b[1:-1:2] = b""
1666        self.assertRaises(BufferError, delslice)
1667        self.assertEqual(b, orig)
1668
1669    @test.support.cpython_only
1670    def test_obsolete_write_lock(self):
1671        _testcapi = import_helper.import_module('_testcapi')
1672        self.assertRaises(BufferError, _testcapi.getbuffer_with_null_view, bytearray())
1673
1674    def test_iterator_pickling2(self):
1675        orig = bytearray(b'abc')
1676        data = list(b'qwerty')
1677        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1678            # initial iterator
1679            itorig = iter(orig)
1680            d = pickle.dumps((itorig, orig), proto)
1681            it, b = pickle.loads(d)
1682            b[:] = data
1683            self.assertEqual(type(it), type(itorig))
1684            self.assertEqual(list(it), data)
1685
1686            # running iterator
1687            next(itorig)
1688            d = pickle.dumps((itorig, orig), proto)
1689            it, b = pickle.loads(d)
1690            b[:] = data
1691            self.assertEqual(type(it), type(itorig))
1692            self.assertEqual(list(it), data[1:])
1693
1694            # empty iterator
1695            for i in range(1, len(orig)):
1696                next(itorig)
1697            d = pickle.dumps((itorig, orig), proto)
1698            it, b = pickle.loads(d)
1699            b[:] = data
1700            self.assertEqual(type(it), type(itorig))
1701            self.assertEqual(list(it), data[len(orig):])
1702
1703            # exhausted iterator
1704            self.assertRaises(StopIteration, next, itorig)
1705            d = pickle.dumps((itorig, orig), proto)
1706            it, b = pickle.loads(d)
1707            b[:] = data
1708            self.assertEqual(list(it), [])
1709
1710    test_exhausted_iterator = test.list_tests.CommonTest.test_exhausted_iterator
1711
1712    def test_iterator_length_hint(self):
1713        # Issue 27443: __length_hint__ can return negative integer
1714        ba = bytearray(b'ab')
1715        it = iter(ba)
1716        next(it)
1717        ba.clear()
1718        # Shouldn't raise an error
1719        self.assertEqual(list(it), [])
1720
1721    def test_repeat_after_setslice(self):
1722        # bpo-42924: * used to copy from the wrong memory location
1723        b = bytearray(b'abc')
1724        b[:2] = b'x'
1725        b1 = b * 1
1726        b3 = b * 3
1727        self.assertEqual(b1, b'xc')
1728        self.assertEqual(b1, b)
1729        self.assertEqual(b3, b'xcxcxc')
1730
1731    def test_mutating_index(self):
1732        class Boom:
1733            def __index__(self):
1734                b.clear()
1735                return 0
1736
1737        with self.subTest("tp_as_mapping"):
1738            b = bytearray(b'Now you see me...')
1739            with self.assertRaises(IndexError):
1740                b[0] = Boom()
1741
1742        with self.subTest("tp_as_sequence"):
1743            _testcapi = import_helper.import_module('_testcapi')
1744            b = bytearray(b'Now you see me...')
1745            with self.assertRaises(IndexError):
1746                _testcapi.sequence_setitem(b, 0, Boom())
1747
1748
1749class AssortedBytesTest(unittest.TestCase):
1750    #
1751    # Test various combinations of bytes and bytearray
1752    #
1753
1754    @check_bytes_warnings
1755    def test_repr_str(self):
1756        for f in str, repr:
1757            self.assertEqual(f(bytearray()), "bytearray(b'')")
1758            self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
1759            self.assertEqual(f(bytearray([0, 1, 254, 255])),
1760                             "bytearray(b'\\x00\\x01\\xfe\\xff')")
1761            self.assertEqual(f(b"abc"), "b'abc'")
1762            self.assertEqual(f(b"'"), '''b"'"''') # '''
1763            self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
1764
1765    @check_bytes_warnings
1766    def test_format(self):
1767        for b in b'abc', bytearray(b'abc'):
1768            self.assertEqual(format(b), str(b))
1769            self.assertEqual(format(b, ''), str(b))
1770            with self.assertRaisesRegex(TypeError,
1771                                        r'\b%s\b' % re.escape(type(b).__name__)):
1772                format(b, 's')
1773
1774    def test_compare_bytes_to_bytearray(self):
1775        self.assertEqual(b"abc" == bytes(b"abc"), True)
1776        self.assertEqual(b"ab" != bytes(b"abc"), True)
1777        self.assertEqual(b"ab" <= bytes(b"abc"), True)
1778        self.assertEqual(b"ab" < bytes(b"abc"), True)
1779        self.assertEqual(b"abc" >= bytes(b"ab"), True)
1780        self.assertEqual(b"abc" > bytes(b"ab"), True)
1781
1782        self.assertEqual(b"abc" != bytes(b"abc"), False)
1783        self.assertEqual(b"ab" == bytes(b"abc"), False)
1784        self.assertEqual(b"ab" > bytes(b"abc"), False)
1785        self.assertEqual(b"ab" >= bytes(b"abc"), False)
1786        self.assertEqual(b"abc" < bytes(b"ab"), False)
1787        self.assertEqual(b"abc" <= bytes(b"ab"), False)
1788
1789        self.assertEqual(bytes(b"abc") == b"abc", True)
1790        self.assertEqual(bytes(b"ab") != b"abc", True)
1791        self.assertEqual(bytes(b"ab") <= b"abc", True)
1792        self.assertEqual(bytes(b"ab") < b"abc", True)
1793        self.assertEqual(bytes(b"abc") >= b"ab", True)
1794        self.assertEqual(bytes(b"abc") > b"ab", True)
1795
1796        self.assertEqual(bytes(b"abc") != b"abc", False)
1797        self.assertEqual(bytes(b"ab") == b"abc", False)
1798        self.assertEqual(bytes(b"ab") > b"abc", False)
1799        self.assertEqual(bytes(b"ab") >= b"abc", False)
1800        self.assertEqual(bytes(b"abc") < b"ab", False)
1801        self.assertEqual(bytes(b"abc") <= b"ab", False)
1802
1803    @test.support.requires_docstrings
1804    def test_doc(self):
1805        self.assertIsNotNone(bytearray.__doc__)
1806        self.assertTrue(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__)
1807        self.assertIsNotNone(bytes.__doc__)
1808        self.assertTrue(bytes.__doc__.startswith("bytes("), bytes.__doc__)
1809
1810    def test_from_bytearray(self):
1811        sample = bytes(b"Hello world\n\x80\x81\xfe\xff")
1812        buf = memoryview(sample)
1813        b = bytearray(buf)
1814        self.assertEqual(b, bytearray(sample))
1815
1816    @check_bytes_warnings
1817    def test_to_str(self):
1818        self.assertEqual(str(b''), "b''")
1819        self.assertEqual(str(b'x'), "b'x'")
1820        self.assertEqual(str(b'\x80'), "b'\\x80'")
1821        self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
1822        self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
1823        self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
1824
1825    def test_literal(self):
1826        tests =  [
1827            (b"Wonderful spam", "Wonderful spam"),
1828            (br"Wonderful spam too", "Wonderful spam too"),
1829            (b"\xaa\x00\000\200", "\xaa\x00\000\200"),
1830            (br"\xaa\x00\000\200", r"\xaa\x00\000\200"),
1831        ]
1832        for b, s in tests:
1833            self.assertEqual(b, bytearray(s, 'latin-1'))
1834        for c in range(128, 256):
1835            self.assertRaises(SyntaxError, eval,
1836                              'b"%s"' % chr(c))
1837
1838    def test_split_bytearray(self):
1839        self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b'])
1840
1841    def test_rsplit_bytearray(self):
1842        self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b'])
1843
1844    def test_return_self(self):
1845        # bytearray.replace must always return a new bytearray
1846        b = bytearray()
1847        self.assertIsNot(b.replace(b'', b''), b)
1848
1849    @unittest.skipUnless(sys.flags.bytes_warning,
1850                         "BytesWarning is needed for this test: use -bb option")
1851    def test_compare(self):
1852        def bytes_warning():
1853            return warnings_helper.check_warnings(('', BytesWarning))
1854        with bytes_warning():
1855            b'' == ''
1856        with bytes_warning():
1857            '' == b''
1858        with bytes_warning():
1859            b'' != ''
1860        with bytes_warning():
1861            '' != b''
1862        with bytes_warning():
1863            bytearray(b'') == ''
1864        with bytes_warning():
1865            '' == bytearray(b'')
1866        with bytes_warning():
1867            bytearray(b'') != ''
1868        with bytes_warning():
1869            '' != bytearray(b'')
1870        with bytes_warning():
1871            b'\0' == 0
1872        with bytes_warning():
1873            0 == b'\0'
1874        with bytes_warning():
1875            b'\0' != 0
1876        with bytes_warning():
1877            0 != b'\0'
1878
1879    # Optimizations:
1880    # __iter__? (optimization)
1881    # __reversed__? (optimization)
1882
1883    # XXX More string methods?  (Those that don't use character properties)
1884
1885    # There are tests in string_tests.py that are more
1886    # comprehensive for things like partition, etc.
1887    # Unfortunately they are all bundled with tests that
1888    # are not appropriate for bytes
1889
1890    # I've started porting some of those into bytearray_tests.py, we should port
1891    # the rest that make sense (the code can be cleaned up to use modern
1892    # unittest methods at the same time).
1893
1894class BytearrayPEP3137Test(unittest.TestCase):
1895    def marshal(self, x):
1896        return bytearray(x)
1897
1898    def test_returns_new_copy(self):
1899        val = self.marshal(b'1234')
1900        # On immutable types these MAY return a reference to themselves
1901        # but on mutable types like bytearray they MUST return a new copy.
1902        for methname in ('zfill', 'rjust', 'ljust', 'center'):
1903            method = getattr(val, methname)
1904            newval = method(3)
1905            self.assertEqual(val, newval)
1906            self.assertIsNot(val, newval,
1907                            methname+' returned self on a mutable object')
1908        for expr in ('val.split()[0]', 'val.rsplit()[0]',
1909                     'val.partition(b".")[0]', 'val.rpartition(b".")[2]',
1910                     'val.splitlines()[0]', 'val.replace(b"", b"")'):
1911            newval = eval(expr)
1912            self.assertEqual(val, newval)
1913            self.assertIsNot(val, newval,
1914                            expr+' returned val on a mutable object')
1915        sep = self.marshal(b'')
1916        newval = sep.join([val])
1917        self.assertEqual(val, newval)
1918        self.assertIsNot(val, newval)
1919
1920
1921class FixedStringTest(test.string_tests.BaseTest):
1922    def fixtype(self, obj):
1923        if isinstance(obj, str):
1924            return self.type2test(obj.encode("utf-8"))
1925        return super().fixtype(obj)
1926
1927    contains_bytes = True
1928
1929class ByteArrayAsStringTest(FixedStringTest, unittest.TestCase):
1930    type2test = bytearray
1931
1932class BytesAsStringTest(FixedStringTest, unittest.TestCase):
1933    type2test = bytes
1934
1935
1936class SubclassTest:
1937
1938    def test_basic(self):
1939        self.assertTrue(issubclass(self.type2test, self.basetype))
1940        self.assertIsInstance(self.type2test(), self.basetype)
1941
1942        a, b = b"abcd", b"efgh"
1943        _a, _b = self.type2test(a), self.type2test(b)
1944
1945        # test comparison operators with subclass instances
1946        self.assertTrue(_a == _a)
1947        self.assertTrue(_a != _b)
1948        self.assertTrue(_a < _b)
1949        self.assertTrue(_a <= _b)
1950        self.assertTrue(_b >= _a)
1951        self.assertTrue(_b > _a)
1952        self.assertIsNot(_a, a)
1953
1954        # test concat of subclass instances
1955        self.assertEqual(a + b, _a + _b)
1956        self.assertEqual(a + b, a + _b)
1957        self.assertEqual(a + b, _a + b)
1958
1959        # test repeat
1960        self.assertTrue(a*5 == _a*5)
1961
1962    def test_join(self):
1963        # Make sure join returns a NEW object for single item sequences
1964        # involving a subclass.
1965        # Make sure that it is of the appropriate type.
1966        s1 = self.type2test(b"abcd")
1967        s2 = self.basetype().join([s1])
1968        self.assertIsNot(s1, s2)
1969        self.assertIs(type(s2), self.basetype, type(s2))
1970
1971        # Test reverse, calling join on subclass
1972        s3 = s1.join([b"abcd"])
1973        self.assertIs(type(s3), self.basetype)
1974
1975    def test_pickle(self):
1976        a = self.type2test(b"abcd")
1977        a.x = 10
1978        a.z = self.type2test(b"efgh")
1979        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1980            b = pickle.loads(pickle.dumps(a, proto))
1981            self.assertNotEqual(id(a), id(b))
1982            self.assertEqual(a, b)
1983            self.assertEqual(a.x, b.x)
1984            self.assertEqual(a.z, b.z)
1985            self.assertEqual(type(a), type(b))
1986            self.assertEqual(type(a.z), type(b.z))
1987            self.assertFalse(hasattr(b, 'y'))
1988
1989    def test_copy(self):
1990        a = self.type2test(b"abcd")
1991        a.x = 10
1992        a.z = self.type2test(b"efgh")
1993        for copy_method in (copy.copy, copy.deepcopy):
1994            b = copy_method(a)
1995            self.assertNotEqual(id(a), id(b))
1996            self.assertEqual(a, b)
1997            self.assertEqual(a.x, b.x)
1998            self.assertEqual(a.z, b.z)
1999            self.assertEqual(type(a), type(b))
2000            self.assertEqual(type(a.z), type(b.z))
2001            self.assertFalse(hasattr(b, 'y'))
2002
2003    def test_fromhex(self):
2004        b = self.type2test.fromhex('1a2B30')
2005        self.assertEqual(b, b'\x1a\x2b\x30')
2006        self.assertIs(type(b), self.type2test)
2007
2008        class B1(self.basetype):
2009            def __new__(cls, value):
2010                me = self.basetype.__new__(cls, value)
2011                me.foo = 'bar'
2012                return me
2013
2014        b = B1.fromhex('1a2B30')
2015        self.assertEqual(b, b'\x1a\x2b\x30')
2016        self.assertIs(type(b), B1)
2017        self.assertEqual(b.foo, 'bar')
2018
2019        class B2(self.basetype):
2020            def __init__(me, *args, **kwargs):
2021                if self.basetype is not bytes:
2022                    self.basetype.__init__(me, *args, **kwargs)
2023                me.foo = 'bar'
2024
2025        b = B2.fromhex('1a2B30')
2026        self.assertEqual(b, b'\x1a\x2b\x30')
2027        self.assertIs(type(b), B2)
2028        self.assertEqual(b.foo, 'bar')
2029
2030
2031class ByteArraySubclass(bytearray):
2032    pass
2033
2034class ByteArraySubclassWithSlots(bytearray):
2035    __slots__ = ('x', 'y', '__dict__')
2036
2037class BytesSubclass(bytes):
2038    pass
2039
2040class OtherBytesSubclass(bytes):
2041    pass
2042
2043class ByteArraySubclassTest(SubclassTest, unittest.TestCase):
2044    basetype = bytearray
2045    type2test = ByteArraySubclass
2046
2047    def test_init_override(self):
2048        class subclass(bytearray):
2049            def __init__(me, newarg=1, *args, **kwargs):
2050                bytearray.__init__(me, *args, **kwargs)
2051        x = subclass(4, b"abcd")
2052        x = subclass(4, source=b"abcd")
2053        self.assertEqual(x, b"abcd")
2054        x = subclass(newarg=4, source=b"abcd")
2055        self.assertEqual(x, b"abcd")
2056
2057class ByteArraySubclassWithSlotsTest(SubclassTest, unittest.TestCase):
2058    basetype = bytearray
2059    type2test = ByteArraySubclassWithSlots
2060
2061class BytesSubclassTest(SubclassTest, unittest.TestCase):
2062    basetype = bytes
2063    type2test = BytesSubclass
2064
2065
2066if __name__ == "__main__":
2067    unittest.main()
2068