• 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 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.restype = py_object
967
968        # basic tests
969        self.assertEqual(PyBytes_FromFormat(b'format'),
970                         b'format')
971        self.assertEqual(PyBytes_FromFormat(b'Hello %s !', b'world'),
972                         b'Hello world !')
973
974        # test formatters
975        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(0)),
976                         b'c=\0')
977        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(ord('@'))),
978                         b'c=@')
979        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(255)),
980                         b'c=\xff')
981        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd',
982                                            c_int(1), c_long(2),
983                                            c_size_t(3)),
984                         b'd=1 ld=2 zd=3')
985        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd',
986                                            c_int(-1), c_long(-2),
987                                            c_size_t(-3)),
988                         b'd=-1 ld=-2 zd=-3')
989        self.assertEqual(PyBytes_FromFormat(b'u=%u lu=%lu zu=%zu',
990                                            c_uint(123), c_ulong(456),
991                                            c_size_t(789)),
992                         b'u=123 lu=456 zu=789')
993        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(123)),
994                         b'i=123')
995        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(-123)),
996                         b'i=-123')
997        self.assertEqual(PyBytes_FromFormat(b'x=%x', c_int(0xabc)),
998                         b'x=abc')
999
1000        sizeof_ptr = ctypes.sizeof(c_char_p)
1001
1002        if os.name == 'nt':
1003            # Windows (MSCRT)
1004            ptr_format = '0x%0{}X'.format(2 * sizeof_ptr)
1005            def ptr_formatter(ptr):
1006                return (ptr_format % ptr)
1007        else:
1008            # UNIX (glibc)
1009            def ptr_formatter(ptr):
1010                return '%#x' % ptr
1011
1012        ptr = 0xabcdef
1013        self.assertEqual(PyBytes_FromFormat(b'ptr=%p', c_char_p(ptr)),
1014                         ('ptr=' + ptr_formatter(ptr)).encode('ascii'))
1015        self.assertEqual(PyBytes_FromFormat(b's=%s', c_char_p(b'cstr')),
1016                         b's=cstr')
1017
1018        # test minimum and maximum integer values
1019        size_max = c_size_t(-1).value
1020        for formatstr, ctypes_type, value, py_formatter in (
1021            (b'%d', c_int, _testcapi.INT_MIN, str),
1022            (b'%d', c_int, _testcapi.INT_MAX, str),
1023            (b'%ld', c_long, _testcapi.LONG_MIN, str),
1024            (b'%ld', c_long, _testcapi.LONG_MAX, str),
1025            (b'%lu', c_ulong, _testcapi.ULONG_MAX, str),
1026            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MIN, str),
1027            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MAX, str),
1028            (b'%zu', c_size_t, size_max, str),
1029            (b'%p', c_char_p, size_max, ptr_formatter),
1030        ):
1031            self.assertEqual(PyBytes_FromFormat(formatstr, ctypes_type(value)),
1032                             py_formatter(value).encode('ascii')),
1033
1034        # width and precision (width is currently ignored)
1035        self.assertEqual(PyBytes_FromFormat(b'%5s', b'a'),
1036                         b'a')
1037        self.assertEqual(PyBytes_FromFormat(b'%.3s', b'abcdef'),
1038                         b'abc')
1039
1040        # '%%' formatter
1041        self.assertEqual(PyBytes_FromFormat(b'%%'),
1042                         b'%')
1043        self.assertEqual(PyBytes_FromFormat(b'[%%]'),
1044                         b'[%]')
1045        self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))),
1046                         b'%_')
1047        self.assertEqual(PyBytes_FromFormat(b'%%s'),
1048                         b'%s')
1049
1050        # Invalid formats and partial formatting
1051        self.assertEqual(PyBytes_FromFormat(b'%'), b'%')
1052        self.assertEqual(PyBytes_FromFormat(b'x=%i y=%', c_int(2), c_int(3)),
1053                         b'x=2 y=%')
1054
1055        # Issue #19969: %c must raise OverflowError for values
1056        # not in the range [0; 255]
1057        self.assertRaises(OverflowError,
1058                          PyBytes_FromFormat, b'%c', c_int(-1))
1059        self.assertRaises(OverflowError,
1060                          PyBytes_FromFormat, b'%c', c_int(256))
1061
1062        # Issue #33817: empty strings
1063        self.assertEqual(PyBytes_FromFormat(b''),
1064                         b'')
1065        self.assertEqual(PyBytes_FromFormat(b'%s', b''),
1066                         b'')
1067
1068    def test_bytes_blocking(self):
1069        class IterationBlocked(list):
1070            __bytes__ = None
1071        i = [0, 1, 2, 3]
1072        self.assertEqual(bytes(i), b'\x00\x01\x02\x03')
1073        self.assertRaises(TypeError, bytes, IterationBlocked(i))
1074
1075        # At least in CPython, because bytes.__new__ and the C API
1076        # PyBytes_FromObject have different fallback rules, integer
1077        # fallback is handled specially, so test separately.
1078        class IntBlocked(int):
1079            __bytes__ = None
1080        self.assertEqual(bytes(3), b'\0\0\0')
1081        self.assertRaises(TypeError, bytes, IntBlocked(3))
1082
1083        # While there is no separately-defined rule for handling bytes
1084        # subclasses differently from other buffer-interface classes,
1085        # an implementation may well special-case them (as CPython 2.x
1086        # str did), so test them separately.
1087        class BytesSubclassBlocked(bytes):
1088            __bytes__ = None
1089        self.assertEqual(bytes(b'ab'), b'ab')
1090        self.assertRaises(TypeError, bytes, BytesSubclassBlocked(b'ab'))
1091
1092        class BufferBlocked(bytearray):
1093            __bytes__ = None
1094        ba, bb = bytearray(b'ab'), BufferBlocked(b'ab')
1095        self.assertEqual(bytes(ba), b'ab')
1096        self.assertRaises(TypeError, bytes, bb)
1097
1098
1099class ByteArrayTest(BaseBytesTest, unittest.TestCase):
1100    type2test = bytearray
1101
1102    def test_getitem_error(self):
1103        b = bytearray(b'python')
1104        msg = "bytearray indices must be integers or slices"
1105        with self.assertRaisesRegex(TypeError, msg):
1106            b['a']
1107
1108    def test_setitem_error(self):
1109        b = bytearray(b'python')
1110        msg = "bytearray indices must be integers or slices"
1111        with self.assertRaisesRegex(TypeError, msg):
1112            b['a'] = "python"
1113
1114    def test_nohash(self):
1115        self.assertRaises(TypeError, hash, bytearray())
1116
1117    def test_bytearray_api(self):
1118        short_sample = b"Hello world\n"
1119        sample = short_sample + b"\0"*(20 - len(short_sample))
1120        tfn = tempfile.mktemp()
1121        try:
1122            # Prepare
1123            with open(tfn, "wb") as f:
1124                f.write(short_sample)
1125            # Test readinto
1126            with open(tfn, "rb") as f:
1127                b = bytearray(20)
1128                n = f.readinto(b)
1129            self.assertEqual(n, len(short_sample))
1130            self.assertEqual(list(b), list(sample))
1131            # Test writing in binary mode
1132            with open(tfn, "wb") as f:
1133                f.write(b)
1134            with open(tfn, "rb") as f:
1135                self.assertEqual(f.read(), sample)
1136            # Text mode is ambiguous; don't test
1137        finally:
1138            try:
1139                os.remove(tfn)
1140            except OSError:
1141                pass
1142
1143    def test_reverse(self):
1144        b = bytearray(b'hello')
1145        self.assertEqual(b.reverse(), None)
1146        self.assertEqual(b, b'olleh')
1147        b = bytearray(b'hello1') # test even number of items
1148        b.reverse()
1149        self.assertEqual(b, b'1olleh')
1150        b = bytearray()
1151        b.reverse()
1152        self.assertFalse(b)
1153
1154    def test_clear(self):
1155        b = bytearray(b'python')
1156        b.clear()
1157        self.assertEqual(b, b'')
1158
1159        b = bytearray(b'')
1160        b.clear()
1161        self.assertEqual(b, b'')
1162
1163        b = bytearray(b'')
1164        b.append(ord('r'))
1165        b.clear()
1166        b.append(ord('p'))
1167        self.assertEqual(b, b'p')
1168
1169    def test_copy(self):
1170        b = bytearray(b'abc')
1171        bb = b.copy()
1172        self.assertEqual(bb, b'abc')
1173
1174        b = bytearray(b'')
1175        bb = b.copy()
1176        self.assertEqual(bb, b'')
1177
1178        # test that it's indeed a copy and not a reference
1179        b = bytearray(b'abc')
1180        bb = b.copy()
1181        self.assertEqual(b, bb)
1182        self.assertIsNot(b, bb)
1183        bb.append(ord('d'))
1184        self.assertEqual(bb, b'abcd')
1185        self.assertEqual(b, b'abc')
1186
1187    def test_regexps(self):
1188        def by(s):
1189            return bytearray(map(ord, s))
1190        b = by("Hello, world")
1191        self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
1192
1193    def test_setitem(self):
1194        b = bytearray([1, 2, 3])
1195        b[1] = 100
1196        self.assertEqual(b, bytearray([1, 100, 3]))
1197        b[-1] = 200
1198        self.assertEqual(b, bytearray([1, 100, 200]))
1199        b[0] = Indexable(10)
1200        self.assertEqual(b, bytearray([10, 100, 200]))
1201        try:
1202            b[3] = 0
1203            self.fail("Didn't raise IndexError")
1204        except IndexError:
1205            pass
1206        try:
1207            b[-10] = 0
1208            self.fail("Didn't raise IndexError")
1209        except IndexError:
1210            pass
1211        try:
1212            b[0] = 256
1213            self.fail("Didn't raise ValueError")
1214        except ValueError:
1215            pass
1216        try:
1217            b[0] = Indexable(-1)
1218            self.fail("Didn't raise ValueError")
1219        except ValueError:
1220            pass
1221        try:
1222            b[0] = None
1223            self.fail("Didn't raise TypeError")
1224        except TypeError:
1225            pass
1226
1227    def test_delitem(self):
1228        b = bytearray(range(10))
1229        del b[0]
1230        self.assertEqual(b, bytearray(range(1, 10)))
1231        del b[-1]
1232        self.assertEqual(b, bytearray(range(1, 9)))
1233        del b[4]
1234        self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1235
1236    def test_setslice(self):
1237        b = bytearray(range(10))
1238        self.assertEqual(list(b), list(range(10)))
1239
1240        b[0:5] = bytearray([1, 1, 1, 1, 1])
1241        self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
1242
1243        del b[0:-5]
1244        self.assertEqual(b, bytearray([5, 6, 7, 8, 9]))
1245
1246        b[0:0] = bytearray([0, 1, 2, 3, 4])
1247        self.assertEqual(b, bytearray(range(10)))
1248
1249        b[-7:-3] = bytearray([100, 101])
1250        self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9]))
1251
1252        b[3:5] = [3, 4, 5, 6]
1253        self.assertEqual(b, bytearray(range(10)))
1254
1255        b[3:0] = [42, 42, 42]
1256        self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
1257
1258        b[3:] = b'foo'
1259        self.assertEqual(b, bytearray([0, 1, 2, 102, 111, 111]))
1260
1261        b[:3] = memoryview(b'foo')
1262        self.assertEqual(b, bytearray([102, 111, 111, 102, 111, 111]))
1263
1264        b[3:4] = []
1265        self.assertEqual(b, bytearray([102, 111, 111, 111, 111]))
1266
1267        for elem in [5, -5, 0, int(10e20), 'str', 2.3,
1268                     ['a', 'b'], [b'a', b'b'], [[]]]:
1269            with self.assertRaises(TypeError):
1270                b[3:4] = elem
1271
1272        for elem in [[254, 255, 256], [-256, 9000]]:
1273            with self.assertRaises(ValueError):
1274                b[3:4] = elem
1275
1276    def test_setslice_extend(self):
1277        # Exercise the resizing logic (see issue #19087)
1278        b = bytearray(range(100))
1279        self.assertEqual(list(b), list(range(100)))
1280        del b[:10]
1281        self.assertEqual(list(b), list(range(10, 100)))
1282        b.extend(range(100, 110))
1283        self.assertEqual(list(b), list(range(10, 110)))
1284
1285    def test_fifo_overrun(self):
1286        # Test for issue #23985, a buffer overrun when implementing a FIFO
1287        # Build Python in pydebug mode for best results.
1288        b = bytearray(10)
1289        b.pop()        # Defeat expanding buffer off-by-one quirk
1290        del b[:1]      # Advance start pointer without reallocating
1291        b += bytes(2)  # Append exactly the number of deleted bytes
1292        del b          # Free memory buffer, allowing pydebug verification
1293
1294    def test_del_expand(self):
1295        # Reducing the size should not expand the buffer (issue #23985)
1296        b = bytearray(10)
1297        size = sys.getsizeof(b)
1298        del b[:1]
1299        self.assertLessEqual(sys.getsizeof(b), size)
1300
1301    def test_extended_set_del_slice(self):
1302        indices = (0, None, 1, 3, 19, 300, 1<<333, sys.maxsize,
1303            -1, -2, -31, -300)
1304        for start in indices:
1305            for stop in indices:
1306                # Skip invalid step 0
1307                for step in indices[1:]:
1308                    L = list(range(255))
1309                    b = bytearray(L)
1310                    # Make sure we have a slice of exactly the right length,
1311                    # but with different data.
1312                    data = L[start:stop:step]
1313                    data.reverse()
1314                    L[start:stop:step] = data
1315                    b[start:stop:step] = data
1316                    self.assertEqual(b, bytearray(L))
1317
1318                    del L[start:stop:step]
1319                    del b[start:stop:step]
1320                    self.assertEqual(b, bytearray(L))
1321
1322    def test_setslice_trap(self):
1323        # This test verifies that we correctly handle assigning self
1324        # to a slice of self (the old Lambert Meertens trap).
1325        b = bytearray(range(256))
1326        b[8:] = b
1327        self.assertEqual(b, bytearray(list(range(8)) + list(range(256))))
1328
1329    def test_iconcat(self):
1330        b = bytearray(b"abc")
1331        b1 = b
1332        b += b"def"
1333        self.assertEqual(b, b"abcdef")
1334        self.assertEqual(b, b1)
1335        self.assertIs(b, b1)
1336        b += b"xyz"
1337        self.assertEqual(b, b"abcdefxyz")
1338        try:
1339            b += ""
1340        except TypeError:
1341            pass
1342        else:
1343            self.fail("bytes += unicode didn't raise TypeError")
1344
1345    def test_irepeat(self):
1346        b = bytearray(b"abc")
1347        b1 = b
1348        b *= 3
1349        self.assertEqual(b, b"abcabcabc")
1350        self.assertEqual(b, b1)
1351        self.assertIs(b, b1)
1352
1353    def test_irepeat_1char(self):
1354        b = bytearray(b"x")
1355        b1 = b
1356        b *= 100
1357        self.assertEqual(b, b"x"*100)
1358        self.assertEqual(b, b1)
1359        self.assertIs(b, b1)
1360
1361    def test_alloc(self):
1362        b = bytearray()
1363        alloc = b.__alloc__()
1364        self.assertGreaterEqual(alloc, 0)
1365        seq = [alloc]
1366        for i in range(100):
1367            b += b"x"
1368            alloc = b.__alloc__()
1369            self.assertGreater(alloc, len(b))  # including trailing null byte
1370            if alloc not in seq:
1371                seq.append(alloc)
1372
1373    def test_init_alloc(self):
1374        b = bytearray()
1375        def g():
1376            for i in range(1, 100):
1377                yield i
1378                a = list(b)
1379                self.assertEqual(a, list(range(1, len(a)+1)))
1380                self.assertEqual(len(b), len(a))
1381                self.assertLessEqual(len(b), i)
1382                alloc = b.__alloc__()
1383                self.assertGreater(alloc, len(b))  # including trailing null byte
1384        b.__init__(g())
1385        self.assertEqual(list(b), list(range(1, 100)))
1386        self.assertEqual(len(b), 99)
1387        alloc = b.__alloc__()
1388        self.assertGreater(alloc, len(b))
1389
1390    def test_extend(self):
1391        orig = b'hello'
1392        a = bytearray(orig)
1393        a.extend(a)
1394        self.assertEqual(a, orig + orig)
1395        self.assertEqual(a[5:], orig)
1396        a = bytearray(b'')
1397        # Test iterators that don't have a __length_hint__
1398        a.extend(map(int, orig * 25))
1399        a.extend(int(x) for x in orig * 25)
1400        self.assertEqual(a, orig * 50)
1401        self.assertEqual(a[-5:], orig)
1402        a = bytearray(b'')
1403        a.extend(iter(map(int, orig * 50)))
1404        self.assertEqual(a, orig * 50)
1405        self.assertEqual(a[-5:], orig)
1406        a = bytearray(b'')
1407        a.extend(list(map(int, orig * 50)))
1408        self.assertEqual(a, orig * 50)
1409        self.assertEqual(a[-5:], orig)
1410        a = bytearray(b'')
1411        self.assertRaises(ValueError, a.extend, [0, 1, 2, 256])
1412        self.assertRaises(ValueError, a.extend, [0, 1, 2, -1])
1413        self.assertEqual(len(a), 0)
1414        a = bytearray(b'')
1415        a.extend([Indexable(ord('a'))])
1416        self.assertEqual(a, b'a')
1417
1418    def test_remove(self):
1419        b = bytearray(b'hello')
1420        b.remove(ord('l'))
1421        self.assertEqual(b, b'helo')
1422        b.remove(ord('l'))
1423        self.assertEqual(b, b'heo')
1424        self.assertRaises(ValueError, lambda: b.remove(ord('l')))
1425        self.assertRaises(ValueError, lambda: b.remove(400))
1426        self.assertRaises(TypeError, lambda: b.remove('e'))
1427        # remove first and last
1428        b.remove(ord('o'))
1429        b.remove(ord('h'))
1430        self.assertEqual(b, b'e')
1431        self.assertRaises(TypeError, lambda: b.remove(b'e'))
1432        b.remove(Indexable(ord('e')))
1433        self.assertEqual(b, b'')
1434
1435        # test values outside of the ascii range: (0, 127)
1436        c = bytearray([126, 127, 128, 129])
1437        c.remove(127)
1438        self.assertEqual(c, bytes([126, 128, 129]))
1439        c.remove(129)
1440        self.assertEqual(c, bytes([126, 128]))
1441
1442    def test_pop(self):
1443        b = bytearray(b'world')
1444        self.assertEqual(b.pop(), ord('d'))
1445        self.assertEqual(b.pop(0), ord('w'))
1446        self.assertEqual(b.pop(-2), ord('r'))
1447        self.assertRaises(IndexError, lambda: b.pop(10))
1448        self.assertRaises(IndexError, lambda: bytearray().pop())
1449        # test for issue #6846
1450        self.assertEqual(bytearray(b'\xff').pop(), 0xff)
1451
1452    def test_nosort(self):
1453        self.assertRaises(AttributeError, lambda: bytearray().sort())
1454
1455    def test_append(self):
1456        b = bytearray(b'hell')
1457        b.append(ord('o'))
1458        self.assertEqual(b, b'hello')
1459        self.assertEqual(b.append(100), None)
1460        b = bytearray()
1461        b.append(ord('A'))
1462        self.assertEqual(len(b), 1)
1463        self.assertRaises(TypeError, lambda: b.append(b'o'))
1464        b = bytearray()
1465        b.append(Indexable(ord('A')))
1466        self.assertEqual(b, b'A')
1467
1468    def test_insert(self):
1469        b = bytearray(b'msssspp')
1470        b.insert(1, ord('i'))
1471        b.insert(4, ord('i'))
1472        b.insert(-2, ord('i'))
1473        b.insert(1000, ord('i'))
1474        self.assertEqual(b, b'mississippi')
1475        self.assertRaises(TypeError, lambda: b.insert(0, b'1'))
1476        b = bytearray()
1477        b.insert(0, Indexable(ord('A')))
1478        self.assertEqual(b, b'A')
1479
1480    def test_copied(self):
1481        # Issue 4348.  Make sure that operations that don't mutate the array
1482        # copy the bytes.
1483        b = bytearray(b'abc')
1484        self.assertIsNot(b, b.replace(b'abc', b'cde', 0))
1485
1486        t = bytearray([i for i in range(256)])
1487        x = bytearray(b'')
1488        self.assertIsNot(x, x.translate(t))
1489
1490    def test_partition_bytearray_doesnt_share_nullstring(self):
1491        a, b, c = bytearray(b"x").partition(b"y")
1492        self.assertEqual(b, b"")
1493        self.assertEqual(c, b"")
1494        self.assertIsNot(b, c)
1495        b += b"!"
1496        self.assertEqual(c, b"")
1497        a, b, c = bytearray(b"x").partition(b"y")
1498        self.assertEqual(b, b"")
1499        self.assertEqual(c, b"")
1500        # Same for rpartition
1501        b, c, a = bytearray(b"x").rpartition(b"y")
1502        self.assertEqual(b, b"")
1503        self.assertEqual(c, b"")
1504        self.assertIsNot(b, c)
1505        b += b"!"
1506        self.assertEqual(c, b"")
1507        c, b, a = bytearray(b"x").rpartition(b"y")
1508        self.assertEqual(b, b"")
1509        self.assertEqual(c, b"")
1510
1511    def test_resize_forbidden(self):
1512        # #4509: can't resize a bytearray when there are buffer exports, even
1513        # if it wouldn't reallocate the underlying buffer.
1514        # Furthermore, no destructive changes to the buffer may be applied
1515        # before raising the error.
1516        b = bytearray(range(10))
1517        v = memoryview(b)
1518        def resize(n):
1519            b[1:-1] = range(n + 1, 2*n - 1)
1520        resize(10)
1521        orig = b[:]
1522        self.assertRaises(BufferError, resize, 11)
1523        self.assertEqual(b, orig)
1524        self.assertRaises(BufferError, resize, 9)
1525        self.assertEqual(b, orig)
1526        self.assertRaises(BufferError, resize, 0)
1527        self.assertEqual(b, orig)
1528        # Other operations implying resize
1529        self.assertRaises(BufferError, b.pop, 0)
1530        self.assertEqual(b, orig)
1531        self.assertRaises(BufferError, b.remove, b[1])
1532        self.assertEqual(b, orig)
1533        def delitem():
1534            del b[1]
1535        self.assertRaises(BufferError, delitem)
1536        self.assertEqual(b, orig)
1537        # deleting a non-contiguous slice
1538        def delslice():
1539            b[1:-1:2] = b""
1540        self.assertRaises(BufferError, delslice)
1541        self.assertEqual(b, orig)
1542
1543    @test.support.cpython_only
1544    def test_obsolete_write_lock(self):
1545        from _testcapi import getbuffer_with_null_view
1546        self.assertRaises(BufferError, getbuffer_with_null_view, bytearray())
1547
1548    def test_iterator_pickling2(self):
1549        orig = bytearray(b'abc')
1550        data = list(b'qwerty')
1551        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1552            # initial iterator
1553            itorig = iter(orig)
1554            d = pickle.dumps((itorig, orig), proto)
1555            it, b = pickle.loads(d)
1556            b[:] = data
1557            self.assertEqual(type(it), type(itorig))
1558            self.assertEqual(list(it), data)
1559
1560            # running iterator
1561            next(itorig)
1562            d = pickle.dumps((itorig, orig), proto)
1563            it, b = pickle.loads(d)
1564            b[:] = data
1565            self.assertEqual(type(it), type(itorig))
1566            self.assertEqual(list(it), data[1:])
1567
1568            # empty iterator
1569            for i in range(1, len(orig)):
1570                next(itorig)
1571            d = pickle.dumps((itorig, orig), proto)
1572            it, b = pickle.loads(d)
1573            b[:] = data
1574            self.assertEqual(type(it), type(itorig))
1575            self.assertEqual(list(it), data[len(orig):])
1576
1577            # exhausted iterator
1578            self.assertRaises(StopIteration, next, itorig)
1579            d = pickle.dumps((itorig, orig), proto)
1580            it, b = pickle.loads(d)
1581            b[:] = data
1582            self.assertEqual(list(it), [])
1583
1584    test_exhausted_iterator = test.list_tests.CommonTest.test_exhausted_iterator
1585
1586    def test_iterator_length_hint(self):
1587        # Issue 27443: __length_hint__ can return negative integer
1588        ba = bytearray(b'ab')
1589        it = iter(ba)
1590        next(it)
1591        ba.clear()
1592        # Shouldn't raise an error
1593        self.assertEqual(list(it), [])
1594
1595
1596class AssortedBytesTest(unittest.TestCase):
1597    #
1598    # Test various combinations of bytes and bytearray
1599    #
1600
1601    @check_bytes_warnings
1602    def test_repr_str(self):
1603        for f in str, repr:
1604            self.assertEqual(f(bytearray()), "bytearray(b'')")
1605            self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
1606            self.assertEqual(f(bytearray([0, 1, 254, 255])),
1607                             "bytearray(b'\\x00\\x01\\xfe\\xff')")
1608            self.assertEqual(f(b"abc"), "b'abc'")
1609            self.assertEqual(f(b"'"), '''b"'"''') # '''
1610            self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
1611
1612    @check_bytes_warnings
1613    def test_format(self):
1614        for b in b'abc', bytearray(b'abc'):
1615            self.assertEqual(format(b), str(b))
1616            self.assertEqual(format(b, ''), str(b))
1617            with self.assertRaisesRegex(TypeError,
1618                                        r'\b%s\b' % re.escape(type(b).__name__)):
1619                format(b, 's')
1620
1621    def test_compare_bytes_to_bytearray(self):
1622        self.assertEqual(b"abc" == bytes(b"abc"), True)
1623        self.assertEqual(b"ab" != bytes(b"abc"), True)
1624        self.assertEqual(b"ab" <= bytes(b"abc"), True)
1625        self.assertEqual(b"ab" < bytes(b"abc"), True)
1626        self.assertEqual(b"abc" >= bytes(b"ab"), True)
1627        self.assertEqual(b"abc" > bytes(b"ab"), True)
1628
1629        self.assertEqual(b"abc" != bytes(b"abc"), False)
1630        self.assertEqual(b"ab" == bytes(b"abc"), False)
1631        self.assertEqual(b"ab" > bytes(b"abc"), False)
1632        self.assertEqual(b"ab" >= bytes(b"abc"), False)
1633        self.assertEqual(b"abc" < bytes(b"ab"), False)
1634        self.assertEqual(b"abc" <= bytes(b"ab"), False)
1635
1636        self.assertEqual(bytes(b"abc") == b"abc", True)
1637        self.assertEqual(bytes(b"ab") != b"abc", True)
1638        self.assertEqual(bytes(b"ab") <= b"abc", True)
1639        self.assertEqual(bytes(b"ab") < b"abc", True)
1640        self.assertEqual(bytes(b"abc") >= b"ab", True)
1641        self.assertEqual(bytes(b"abc") > b"ab", True)
1642
1643        self.assertEqual(bytes(b"abc") != b"abc", False)
1644        self.assertEqual(bytes(b"ab") == b"abc", False)
1645        self.assertEqual(bytes(b"ab") > b"abc", False)
1646        self.assertEqual(bytes(b"ab") >= b"abc", False)
1647        self.assertEqual(bytes(b"abc") < b"ab", False)
1648        self.assertEqual(bytes(b"abc") <= b"ab", False)
1649
1650    @test.support.requires_docstrings
1651    def test_doc(self):
1652        self.assertIsNotNone(bytearray.__doc__)
1653        self.assertTrue(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__)
1654        self.assertIsNotNone(bytes.__doc__)
1655        self.assertTrue(bytes.__doc__.startswith("bytes("), bytes.__doc__)
1656
1657    def test_from_bytearray(self):
1658        sample = bytes(b"Hello world\n\x80\x81\xfe\xff")
1659        buf = memoryview(sample)
1660        b = bytearray(buf)
1661        self.assertEqual(b, bytearray(sample))
1662
1663    @check_bytes_warnings
1664    def test_to_str(self):
1665        self.assertEqual(str(b''), "b''")
1666        self.assertEqual(str(b'x'), "b'x'")
1667        self.assertEqual(str(b'\x80'), "b'\\x80'")
1668        self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
1669        self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
1670        self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
1671
1672    def test_literal(self):
1673        tests =  [
1674            (b"Wonderful spam", "Wonderful spam"),
1675            (br"Wonderful spam too", "Wonderful spam too"),
1676            (b"\xaa\x00\000\200", "\xaa\x00\000\200"),
1677            (br"\xaa\x00\000\200", r"\xaa\x00\000\200"),
1678        ]
1679        for b, s in tests:
1680            self.assertEqual(b, bytearray(s, 'latin-1'))
1681        for c in range(128, 256):
1682            self.assertRaises(SyntaxError, eval,
1683                              'b"%s"' % chr(c))
1684
1685    def test_split_bytearray(self):
1686        self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b'])
1687
1688    def test_rsplit_bytearray(self):
1689        self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b'])
1690
1691    def test_return_self(self):
1692        # bytearray.replace must always return a new bytearray
1693        b = bytearray()
1694        self.assertIsNot(b.replace(b'', b''), b)
1695
1696    @unittest.skipUnless(sys.flags.bytes_warning,
1697                         "BytesWarning is needed for this test: use -bb option")
1698    def test_compare(self):
1699        def bytes_warning():
1700            return test.support.check_warnings(('', BytesWarning))
1701        with bytes_warning():
1702            b'' == ''
1703        with bytes_warning():
1704            '' == b''
1705        with bytes_warning():
1706            b'' != ''
1707        with bytes_warning():
1708            '' != b''
1709        with bytes_warning():
1710            bytearray(b'') == ''
1711        with bytes_warning():
1712            '' == bytearray(b'')
1713        with bytes_warning():
1714            bytearray(b'') != ''
1715        with bytes_warning():
1716            '' != bytearray(b'')
1717        with bytes_warning():
1718            b'\0' == 0
1719        with bytes_warning():
1720            0 == b'\0'
1721        with bytes_warning():
1722            b'\0' != 0
1723        with bytes_warning():
1724            0 != b'\0'
1725
1726    # Optimizations:
1727    # __iter__? (optimization)
1728    # __reversed__? (optimization)
1729
1730    # XXX More string methods?  (Those that don't use character properties)
1731
1732    # There are tests in string_tests.py that are more
1733    # comprehensive for things like partition, etc.
1734    # Unfortunately they are all bundled with tests that
1735    # are not appropriate for bytes
1736
1737    # I've started porting some of those into bytearray_tests.py, we should port
1738    # the rest that make sense (the code can be cleaned up to use modern
1739    # unittest methods at the same time).
1740
1741class BytearrayPEP3137Test(unittest.TestCase):
1742    def marshal(self, x):
1743        return bytearray(x)
1744
1745    def test_returns_new_copy(self):
1746        val = self.marshal(b'1234')
1747        # On immutable types these MAY return a reference to themselves
1748        # but on mutable types like bytearray they MUST return a new copy.
1749        for methname in ('zfill', 'rjust', 'ljust', 'center'):
1750            method = getattr(val, methname)
1751            newval = method(3)
1752            self.assertEqual(val, newval)
1753            self.assertIsNot(val, newval,
1754                            methname+' returned self on a mutable object')
1755        for expr in ('val.split()[0]', 'val.rsplit()[0]',
1756                     'val.partition(b".")[0]', 'val.rpartition(b".")[2]',
1757                     'val.splitlines()[0]', 'val.replace(b"", b"")'):
1758            newval = eval(expr)
1759            self.assertEqual(val, newval)
1760            self.assertIsNot(val, newval,
1761                            expr+' returned val on a mutable object')
1762        sep = self.marshal(b'')
1763        newval = sep.join([val])
1764        self.assertEqual(val, newval)
1765        self.assertIsNot(val, newval)
1766
1767
1768class FixedStringTest(test.string_tests.BaseTest):
1769    def fixtype(self, obj):
1770        if isinstance(obj, str):
1771            return self.type2test(obj.encode("utf-8"))
1772        return super().fixtype(obj)
1773
1774    contains_bytes = True
1775
1776class ByteArrayAsStringTest(FixedStringTest, unittest.TestCase):
1777    type2test = bytearray
1778
1779class BytesAsStringTest(FixedStringTest, unittest.TestCase):
1780    type2test = bytes
1781
1782
1783class SubclassTest:
1784
1785    def test_basic(self):
1786        self.assertTrue(issubclass(self.type2test, self.basetype))
1787        self.assertIsInstance(self.type2test(), self.basetype)
1788
1789        a, b = b"abcd", b"efgh"
1790        _a, _b = self.type2test(a), self.type2test(b)
1791
1792        # test comparison operators with subclass instances
1793        self.assertTrue(_a == _a)
1794        self.assertTrue(_a != _b)
1795        self.assertTrue(_a < _b)
1796        self.assertTrue(_a <= _b)
1797        self.assertTrue(_b >= _a)
1798        self.assertTrue(_b > _a)
1799        self.assertIsNot(_a, a)
1800
1801        # test concat of subclass instances
1802        self.assertEqual(a + b, _a + _b)
1803        self.assertEqual(a + b, a + _b)
1804        self.assertEqual(a + b, _a + b)
1805
1806        # test repeat
1807        self.assertTrue(a*5 == _a*5)
1808
1809    def test_join(self):
1810        # Make sure join returns a NEW object for single item sequences
1811        # involving a subclass.
1812        # Make sure that it is of the appropriate type.
1813        s1 = self.type2test(b"abcd")
1814        s2 = self.basetype().join([s1])
1815        self.assertIsNot(s1, s2)
1816        self.assertIs(type(s2), self.basetype, type(s2))
1817
1818        # Test reverse, calling join on subclass
1819        s3 = s1.join([b"abcd"])
1820        self.assertIs(type(s3), self.basetype)
1821
1822    def test_pickle(self):
1823        a = self.type2test(b"abcd")
1824        a.x = 10
1825        a.y = self.type2test(b"efgh")
1826        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1827            b = pickle.loads(pickle.dumps(a, proto))
1828            self.assertNotEqual(id(a), id(b))
1829            self.assertEqual(a, b)
1830            self.assertEqual(a.x, b.x)
1831            self.assertEqual(a.y, b.y)
1832            self.assertEqual(type(a), type(b))
1833            self.assertEqual(type(a.y), type(b.y))
1834
1835    def test_copy(self):
1836        a = self.type2test(b"abcd")
1837        a.x = 10
1838        a.y = self.type2test(b"efgh")
1839        for copy_method in (copy.copy, copy.deepcopy):
1840            b = copy_method(a)
1841            self.assertNotEqual(id(a), id(b))
1842            self.assertEqual(a, b)
1843            self.assertEqual(a.x, b.x)
1844            self.assertEqual(a.y, b.y)
1845            self.assertEqual(type(a), type(b))
1846            self.assertEqual(type(a.y), type(b.y))
1847
1848    def test_fromhex(self):
1849        b = self.type2test.fromhex('1a2B30')
1850        self.assertEqual(b, b'\x1a\x2b\x30')
1851        self.assertIs(type(b), self.type2test)
1852
1853        class B1(self.basetype):
1854            def __new__(cls, value):
1855                me = self.basetype.__new__(cls, value)
1856                me.foo = 'bar'
1857                return me
1858
1859        b = B1.fromhex('1a2B30')
1860        self.assertEqual(b, b'\x1a\x2b\x30')
1861        self.assertIs(type(b), B1)
1862        self.assertEqual(b.foo, 'bar')
1863
1864        class B2(self.basetype):
1865            def __init__(me, *args, **kwargs):
1866                if self.basetype is not bytes:
1867                    self.basetype.__init__(me, *args, **kwargs)
1868                me.foo = 'bar'
1869
1870        b = B2.fromhex('1a2B30')
1871        self.assertEqual(b, b'\x1a\x2b\x30')
1872        self.assertIs(type(b), B2)
1873        self.assertEqual(b.foo, 'bar')
1874
1875
1876class ByteArraySubclass(bytearray):
1877    pass
1878
1879class BytesSubclass(bytes):
1880    pass
1881
1882class OtherBytesSubclass(bytes):
1883    pass
1884
1885class ByteArraySubclassTest(SubclassTest, unittest.TestCase):
1886    basetype = bytearray
1887    type2test = ByteArraySubclass
1888
1889    def test_init_override(self):
1890        class subclass(bytearray):
1891            def __init__(me, newarg=1, *args, **kwargs):
1892                bytearray.__init__(me, *args, **kwargs)
1893        x = subclass(4, b"abcd")
1894        x = subclass(4, source=b"abcd")
1895        self.assertEqual(x, b"abcd")
1896        x = subclass(newarg=4, source=b"abcd")
1897        self.assertEqual(x, b"abcd")
1898
1899
1900class BytesSubclassTest(SubclassTest, unittest.TestCase):
1901    basetype = bytes
1902    type2test = BytesSubclass
1903
1904
1905if __name__ == "__main__":
1906    unittest.main()
1907