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