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