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