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