1"""Test the arraymodule. 2 Roger E. Masse 3""" 4 5import collections.abc 6import unittest 7from test import support 8from test.support import os_helper 9from test.support import _2G 10import weakref 11import pickle 12import operator 13import struct 14import sys 15 16import array 17from array import _array_reconstructor as array_reconstructor 18 19sizeof_wchar = array.array('u').itemsize 20 21 22class ArraySubclass(array.array): 23 pass 24 25class ArraySubclassWithKwargs(array.array): 26 def __init__(self, typecode, newarg=None): 27 array.array.__init__(self) 28 29typecodes = 'ubBhHiIlLfdqQ' 30 31class MiscTest(unittest.TestCase): 32 33 def test_array_is_sequence(self): 34 self.assertIsInstance(array.array("B"), collections.abc.MutableSequence) 35 self.assertIsInstance(array.array("B"), collections.abc.Reversible) 36 37 def test_bad_constructor(self): 38 self.assertRaises(TypeError, array.array) 39 self.assertRaises(TypeError, array.array, spam=42) 40 self.assertRaises(TypeError, array.array, 'xx') 41 self.assertRaises(ValueError, array.array, 'x') 42 43 @support.cpython_only 44 def test_disallow_instantiation(self): 45 my_array = array.array("I") 46 support.check_disallow_instantiation( 47 self, type(iter(my_array)), my_array 48 ) 49 50 @support.cpython_only 51 def test_immutable(self): 52 # bpo-43908: check that array.array is immutable 53 with self.assertRaises(TypeError): 54 array.array.foo = 1 55 56 def test_empty(self): 57 # Exercise code for handling zero-length arrays 58 a = array.array('B') 59 a[:] = a 60 self.assertEqual(len(a), 0) 61 self.assertEqual(len(a + a), 0) 62 self.assertEqual(len(a * 3), 0) 63 a += a 64 self.assertEqual(len(a), 0) 65 66 67# Machine format codes. 68# 69# Search for "enum machine_format_code" in Modules/arraymodule.c to get the 70# authoritative values. 71UNKNOWN_FORMAT = -1 72UNSIGNED_INT8 = 0 73SIGNED_INT8 = 1 74UNSIGNED_INT16_LE = 2 75UNSIGNED_INT16_BE = 3 76SIGNED_INT16_LE = 4 77SIGNED_INT16_BE = 5 78UNSIGNED_INT32_LE = 6 79UNSIGNED_INT32_BE = 7 80SIGNED_INT32_LE = 8 81SIGNED_INT32_BE = 9 82UNSIGNED_INT64_LE = 10 83UNSIGNED_INT64_BE = 11 84SIGNED_INT64_LE = 12 85SIGNED_INT64_BE = 13 86IEEE_754_FLOAT_LE = 14 87IEEE_754_FLOAT_BE = 15 88IEEE_754_DOUBLE_LE = 16 89IEEE_754_DOUBLE_BE = 17 90UTF16_LE = 18 91UTF16_BE = 19 92UTF32_LE = 20 93UTF32_BE = 21 94 95class ArrayReconstructorTest(unittest.TestCase): 96 97 def test_error(self): 98 self.assertRaises(TypeError, array_reconstructor, 99 "", "b", 0, b"") 100 self.assertRaises(TypeError, array_reconstructor, 101 str, "b", 0, b"") 102 self.assertRaises(TypeError, array_reconstructor, 103 array.array, "b", '', b"") 104 self.assertRaises(TypeError, array_reconstructor, 105 array.array, "b", 0, "") 106 self.assertRaises(ValueError, array_reconstructor, 107 array.array, "?", 0, b"") 108 self.assertRaises(ValueError, array_reconstructor, 109 array.array, "b", UNKNOWN_FORMAT, b"") 110 self.assertRaises(ValueError, array_reconstructor, 111 array.array, "b", 22, b"") 112 self.assertRaises(ValueError, array_reconstructor, 113 array.array, "d", 16, b"a") 114 115 def test_numbers(self): 116 testcases = ( 117 (['B', 'H', 'I', 'L'], UNSIGNED_INT8, '=BBBB', 118 [0x80, 0x7f, 0, 0xff]), 119 (['b', 'h', 'i', 'l'], SIGNED_INT8, '=bbb', 120 [-0x80, 0x7f, 0]), 121 (['H', 'I', 'L'], UNSIGNED_INT16_LE, '<HHHH', 122 [0x8000, 0x7fff, 0, 0xffff]), 123 (['H', 'I', 'L'], UNSIGNED_INT16_BE, '>HHHH', 124 [0x8000, 0x7fff, 0, 0xffff]), 125 (['h', 'i', 'l'], SIGNED_INT16_LE, '<hhh', 126 [-0x8000, 0x7fff, 0]), 127 (['h', 'i', 'l'], SIGNED_INT16_BE, '>hhh', 128 [-0x8000, 0x7fff, 0]), 129 (['I', 'L'], UNSIGNED_INT32_LE, '<IIII', 130 [1<<31, (1<<31)-1, 0, (1<<32)-1]), 131 (['I', 'L'], UNSIGNED_INT32_BE, '>IIII', 132 [1<<31, (1<<31)-1, 0, (1<<32)-1]), 133 (['i', 'l'], SIGNED_INT32_LE, '<iii', 134 [-1<<31, (1<<31)-1, 0]), 135 (['i', 'l'], SIGNED_INT32_BE, '>iii', 136 [-1<<31, (1<<31)-1, 0]), 137 (['L'], UNSIGNED_INT64_LE, '<QQQQ', 138 [1<<31, (1<<31)-1, 0, (1<<32)-1]), 139 (['L'], UNSIGNED_INT64_BE, '>QQQQ', 140 [1<<31, (1<<31)-1, 0, (1<<32)-1]), 141 (['l'], SIGNED_INT64_LE, '<qqq', 142 [-1<<31, (1<<31)-1, 0]), 143 (['l'], SIGNED_INT64_BE, '>qqq', 144 [-1<<31, (1<<31)-1, 0]), 145 # The following tests for INT64 will raise an OverflowError 146 # when run on a 32-bit machine. The tests are simply skipped 147 # in that case. 148 (['L'], UNSIGNED_INT64_LE, '<QQQQ', 149 [1<<63, (1<<63)-1, 0, (1<<64)-1]), 150 (['L'], UNSIGNED_INT64_BE, '>QQQQ', 151 [1<<63, (1<<63)-1, 0, (1<<64)-1]), 152 (['l'], SIGNED_INT64_LE, '<qqq', 153 [-1<<63, (1<<63)-1, 0]), 154 (['l'], SIGNED_INT64_BE, '>qqq', 155 [-1<<63, (1<<63)-1, 0]), 156 (['f'], IEEE_754_FLOAT_LE, '<ffff', 157 [16711938.0, float('inf'), float('-inf'), -0.0]), 158 (['f'], IEEE_754_FLOAT_BE, '>ffff', 159 [16711938.0, float('inf'), float('-inf'), -0.0]), 160 (['d'], IEEE_754_DOUBLE_LE, '<dddd', 161 [9006104071832581.0, float('inf'), float('-inf'), -0.0]), 162 (['d'], IEEE_754_DOUBLE_BE, '>dddd', 163 [9006104071832581.0, float('inf'), float('-inf'), -0.0]) 164 ) 165 for testcase in testcases: 166 valid_typecodes, mformat_code, struct_fmt, values = testcase 167 arraystr = struct.pack(struct_fmt, *values) 168 for typecode in valid_typecodes: 169 try: 170 a = array.array(typecode, values) 171 except OverflowError: 172 continue # Skip this test case. 173 b = array_reconstructor( 174 array.array, typecode, mformat_code, arraystr) 175 self.assertEqual(a, b, 176 msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase)) 177 178 def test_unicode(self): 179 teststr = "Bonne Journ\xe9e \U0002030a\U00020347" 180 testcases = ( 181 (UTF16_LE, "UTF-16-LE"), 182 (UTF16_BE, "UTF-16-BE"), 183 (UTF32_LE, "UTF-32-LE"), 184 (UTF32_BE, "UTF-32-BE") 185 ) 186 for testcase in testcases: 187 mformat_code, encoding = testcase 188 a = array.array('u', teststr) 189 b = array_reconstructor( 190 array.array, 'u', mformat_code, teststr.encode(encoding)) 191 self.assertEqual(a, b, 192 msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase)) 193 194 195class BaseTest: 196 # Required class attributes (provided by subclasses 197 # typecode: the typecode to test 198 # example: an initializer usable in the constructor for this type 199 # smallerexample: the same length as example, but smaller 200 # biggerexample: the same length as example, but bigger 201 # outside: An entry that is not in example 202 # minitemsize: the minimum guaranteed itemsize 203 204 def assertEntryEqual(self, entry1, entry2): 205 self.assertEqual(entry1, entry2) 206 207 def badtypecode(self): 208 # Return a typecode that is different from our own 209 return typecodes[(typecodes.index(self.typecode)+1) % len(typecodes)] 210 211 def test_constructor(self): 212 a = array.array(self.typecode) 213 self.assertEqual(a.typecode, self.typecode) 214 self.assertGreaterEqual(a.itemsize, self.minitemsize) 215 self.assertRaises(TypeError, array.array, self.typecode, None) 216 217 def test_len(self): 218 a = array.array(self.typecode) 219 a.append(self.example[0]) 220 self.assertEqual(len(a), 1) 221 222 a = array.array(self.typecode, self.example) 223 self.assertEqual(len(a), len(self.example)) 224 225 def test_buffer_info(self): 226 a = array.array(self.typecode, self.example) 227 self.assertRaises(TypeError, a.buffer_info, 42) 228 bi = a.buffer_info() 229 self.assertIsInstance(bi, tuple) 230 self.assertEqual(len(bi), 2) 231 self.assertIsInstance(bi[0], int) 232 self.assertIsInstance(bi[1], int) 233 self.assertEqual(bi[1], len(a)) 234 235 def test_byteswap(self): 236 if self.typecode == 'u': 237 example = '\U00100100' 238 else: 239 example = self.example 240 a = array.array(self.typecode, example) 241 self.assertRaises(TypeError, a.byteswap, 42) 242 if a.itemsize in (1, 2, 4, 8): 243 b = array.array(self.typecode, example) 244 b.byteswap() 245 if a.itemsize==1: 246 self.assertEqual(a, b) 247 else: 248 self.assertNotEqual(a, b) 249 b.byteswap() 250 self.assertEqual(a, b) 251 252 def test_copy(self): 253 import copy 254 a = array.array(self.typecode, self.example) 255 b = copy.copy(a) 256 self.assertNotEqual(id(a), id(b)) 257 self.assertEqual(a, b) 258 259 def test_deepcopy(self): 260 import copy 261 a = array.array(self.typecode, self.example) 262 b = copy.deepcopy(a) 263 self.assertNotEqual(id(a), id(b)) 264 self.assertEqual(a, b) 265 266 def test_reduce_ex(self): 267 a = array.array(self.typecode, self.example) 268 for protocol in range(3): 269 self.assertIs(a.__reduce_ex__(protocol)[0], array.array) 270 for protocol in range(3, pickle.HIGHEST_PROTOCOL + 1): 271 self.assertIs(a.__reduce_ex__(protocol)[0], array_reconstructor) 272 273 def test_pickle(self): 274 for protocol in range(pickle.HIGHEST_PROTOCOL + 1): 275 a = array.array(self.typecode, self.example) 276 b = pickle.loads(pickle.dumps(a, protocol)) 277 self.assertNotEqual(id(a), id(b)) 278 self.assertEqual(a, b) 279 280 a = ArraySubclass(self.typecode, self.example) 281 a.x = 10 282 b = pickle.loads(pickle.dumps(a, protocol)) 283 self.assertNotEqual(id(a), id(b)) 284 self.assertEqual(a, b) 285 self.assertEqual(a.x, b.x) 286 self.assertEqual(type(a), type(b)) 287 288 def test_pickle_for_empty_array(self): 289 for protocol in range(pickle.HIGHEST_PROTOCOL + 1): 290 a = array.array(self.typecode) 291 b = pickle.loads(pickle.dumps(a, protocol)) 292 self.assertNotEqual(id(a), id(b)) 293 self.assertEqual(a, b) 294 295 a = ArraySubclass(self.typecode) 296 a.x = 10 297 b = pickle.loads(pickle.dumps(a, protocol)) 298 self.assertNotEqual(id(a), id(b)) 299 self.assertEqual(a, b) 300 self.assertEqual(a.x, b.x) 301 self.assertEqual(type(a), type(b)) 302 303 def test_iterator_pickle(self): 304 orig = array.array(self.typecode, self.example) 305 data = list(orig) 306 data2 = data[::-1] 307 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 308 # initial iterator 309 itorig = iter(orig) 310 d = pickle.dumps((itorig, orig), proto) 311 it, a = pickle.loads(d) 312 a.fromlist(data2) 313 self.assertEqual(type(it), type(itorig)) 314 self.assertEqual(list(it), data + data2) 315 316 # running iterator 317 next(itorig) 318 d = pickle.dumps((itorig, orig), proto) 319 it, a = pickle.loads(d) 320 a.fromlist(data2) 321 self.assertEqual(type(it), type(itorig)) 322 self.assertEqual(list(it), data[1:] + data2) 323 324 # empty iterator 325 for i in range(1, len(data)): 326 next(itorig) 327 d = pickle.dumps((itorig, orig), proto) 328 it, a = pickle.loads(d) 329 a.fromlist(data2) 330 self.assertEqual(type(it), type(itorig)) 331 self.assertEqual(list(it), data2) 332 333 # exhausted iterator 334 self.assertRaises(StopIteration, next, itorig) 335 d = pickle.dumps((itorig, orig), proto) 336 it, a = pickle.loads(d) 337 a.fromlist(data2) 338 self.assertEqual(list(it), []) 339 340 def test_exhausted_iterator(self): 341 a = array.array(self.typecode, self.example) 342 self.assertEqual(list(a), list(self.example)) 343 exhit = iter(a) 344 empit = iter(a) 345 for x in exhit: # exhaust the iterator 346 next(empit) # not exhausted 347 a.append(self.outside) 348 self.assertEqual(list(exhit), []) 349 self.assertEqual(list(empit), [self.outside]) 350 self.assertEqual(list(a), list(self.example) + [self.outside]) 351 352 def test_reverse_iterator(self): 353 a = array.array(self.typecode, self.example) 354 self.assertEqual(list(a), list(self.example)) 355 self.assertEqual(list(reversed(a)), list(iter(a))[::-1]) 356 357 def test_reverse_iterator_picking(self): 358 orig = array.array(self.typecode, self.example) 359 data = list(orig) 360 data2 = [self.outside] + data 361 rev_data = data[len(data)-2::-1] + [self.outside] 362 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 363 # initial iterator 364 itorig = reversed(orig) 365 d = pickle.dumps((itorig, orig), proto) 366 it, a = pickle.loads(d) 367 a.insert(0, self.outside) 368 self.assertEqual(type(it), type(itorig)) 369 self.assertEqual(list(it), rev_data) 370 self.assertEqual(list(a), data2) 371 372 # running iterator 373 next(itorig) 374 d = pickle.dumps((itorig, orig), proto) 375 it, a = pickle.loads(d) 376 a.insert(0, self.outside) 377 self.assertEqual(type(it), type(itorig)) 378 self.assertEqual(list(it), rev_data[1:]) 379 self.assertEqual(list(a), data2) 380 381 # empty iterator 382 for i in range(1, len(data)): 383 next(itorig) 384 d = pickle.dumps((itorig, orig), proto) 385 it, a = pickle.loads(d) 386 a.insert(0, self.outside) 387 self.assertEqual(type(it), type(itorig)) 388 self.assertEqual(list(it), []) 389 self.assertEqual(list(a), data2) 390 391 # exhausted iterator 392 self.assertRaises(StopIteration, next, itorig) 393 d = pickle.dumps((itorig, orig), proto) 394 it, a = pickle.loads(d) 395 a.insert(0, self.outside) 396 self.assertEqual(list(it), []) 397 self.assertEqual(list(a), data2) 398 399 def test_exhausted_reverse_iterator(self): 400 a = array.array(self.typecode, self.example) 401 self.assertEqual(list(a), list(self.example)) 402 exhit = reversed(a) 403 empit = reversed(a) 404 for x in exhit: # exhaust the iterator 405 next(empit) # Pointing past the 0th position. 406 a.insert(0, self.outside) 407 self.assertEqual(list(exhit), []) 408 # The iterator index points past the 0th position so inserting 409 # an element in the beginning does not make it appear. 410 self.assertEqual(list(empit), []) 411 self.assertEqual(list(a), [self.outside] + list(self.example)) 412 413 def test_insert(self): 414 a = array.array(self.typecode, self.example) 415 a.insert(0, self.example[0]) 416 self.assertEqual(len(a), 1+len(self.example)) 417 self.assertEqual(a[0], a[1]) 418 self.assertRaises(TypeError, a.insert) 419 self.assertRaises(TypeError, a.insert, None) 420 self.assertRaises(TypeError, a.insert, 0, None) 421 422 a = array.array(self.typecode, self.example) 423 a.insert(-1, self.example[0]) 424 self.assertEqual( 425 a, 426 array.array( 427 self.typecode, 428 self.example[:-1] + self.example[:1] + self.example[-1:] 429 ) 430 ) 431 432 a = array.array(self.typecode, self.example) 433 a.insert(-1000, self.example[0]) 434 self.assertEqual( 435 a, 436 array.array(self.typecode, self.example[:1] + self.example) 437 ) 438 439 a = array.array(self.typecode, self.example) 440 a.insert(1000, self.example[0]) 441 self.assertEqual( 442 a, 443 array.array(self.typecode, self.example + self.example[:1]) 444 ) 445 446 def test_tofromfile(self): 447 a = array.array(self.typecode, 2*self.example) 448 self.assertRaises(TypeError, a.tofile) 449 os_helper.unlink(os_helper.TESTFN) 450 f = open(os_helper.TESTFN, 'wb') 451 try: 452 a.tofile(f) 453 f.close() 454 b = array.array(self.typecode) 455 f = open(os_helper.TESTFN, 'rb') 456 self.assertRaises(TypeError, b.fromfile) 457 b.fromfile(f, len(self.example)) 458 self.assertEqual(b, array.array(self.typecode, self.example)) 459 self.assertNotEqual(a, b) 460 self.assertRaises(EOFError, b.fromfile, f, len(self.example)+1) 461 self.assertEqual(a, b) 462 f.close() 463 finally: 464 if not f.closed: 465 f.close() 466 os_helper.unlink(os_helper.TESTFN) 467 468 def test_fromfile_ioerror(self): 469 # Issue #5395: Check if fromfile raises a proper OSError 470 # instead of EOFError. 471 a = array.array(self.typecode) 472 f = open(os_helper.TESTFN, 'wb') 473 try: 474 self.assertRaises(OSError, a.fromfile, f, len(self.example)) 475 finally: 476 f.close() 477 os_helper.unlink(os_helper.TESTFN) 478 479 def test_filewrite(self): 480 a = array.array(self.typecode, 2*self.example) 481 f = open(os_helper.TESTFN, 'wb') 482 try: 483 f.write(a) 484 f.close() 485 b = array.array(self.typecode) 486 f = open(os_helper.TESTFN, 'rb') 487 b.fromfile(f, len(self.example)) 488 self.assertEqual(b, array.array(self.typecode, self.example)) 489 self.assertNotEqual(a, b) 490 b.fromfile(f, len(self.example)) 491 self.assertEqual(a, b) 492 f.close() 493 finally: 494 if not f.closed: 495 f.close() 496 os_helper.unlink(os_helper.TESTFN) 497 498 def test_tofromlist(self): 499 a = array.array(self.typecode, 2*self.example) 500 b = array.array(self.typecode) 501 self.assertRaises(TypeError, a.tolist, 42) 502 self.assertRaises(TypeError, b.fromlist) 503 self.assertRaises(TypeError, b.fromlist, 42) 504 self.assertRaises(TypeError, b.fromlist, [None]) 505 b.fromlist(a.tolist()) 506 self.assertEqual(a, b) 507 508 def test_tofrombytes(self): 509 a = array.array(self.typecode, 2*self.example) 510 b = array.array(self.typecode) 511 self.assertRaises(TypeError, a.tobytes, 42) 512 self.assertRaises(TypeError, b.frombytes) 513 self.assertRaises(TypeError, b.frombytes, 42) 514 b.frombytes(a.tobytes()) 515 c = array.array(self.typecode, bytearray(a.tobytes())) 516 self.assertEqual(a, b) 517 self.assertEqual(a, c) 518 if a.itemsize>1: 519 self.assertRaises(ValueError, b.frombytes, b"x") 520 521 def test_fromarray(self): 522 a = array.array(self.typecode, self.example) 523 b = array.array(self.typecode, a) 524 self.assertEqual(a, b) 525 526 def test_repr(self): 527 a = array.array(self.typecode, 2*self.example) 528 self.assertEqual(a, eval(repr(a), {"array": array.array})) 529 530 a = array.array(self.typecode) 531 self.assertEqual(repr(a), "array('%s')" % self.typecode) 532 533 def test_str(self): 534 a = array.array(self.typecode, 2*self.example) 535 str(a) 536 537 def test_cmp(self): 538 a = array.array(self.typecode, self.example) 539 self.assertIs(a == 42, False) 540 self.assertIs(a != 42, True) 541 542 self.assertIs(a == a, True) 543 self.assertIs(a != a, False) 544 self.assertIs(a < a, False) 545 self.assertIs(a <= a, True) 546 self.assertIs(a > a, False) 547 self.assertIs(a >= a, True) 548 549 al = array.array(self.typecode, self.smallerexample) 550 ab = array.array(self.typecode, self.biggerexample) 551 552 self.assertIs(a == 2*a, False) 553 self.assertIs(a != 2*a, True) 554 self.assertIs(a < 2*a, True) 555 self.assertIs(a <= 2*a, True) 556 self.assertIs(a > 2*a, False) 557 self.assertIs(a >= 2*a, False) 558 559 self.assertIs(a == al, False) 560 self.assertIs(a != al, True) 561 self.assertIs(a < al, False) 562 self.assertIs(a <= al, False) 563 self.assertIs(a > al, True) 564 self.assertIs(a >= al, True) 565 566 self.assertIs(a == ab, False) 567 self.assertIs(a != ab, True) 568 self.assertIs(a < ab, True) 569 self.assertIs(a <= ab, True) 570 self.assertIs(a > ab, False) 571 self.assertIs(a >= ab, False) 572 573 def test_add(self): 574 a = array.array(self.typecode, self.example) \ 575 + array.array(self.typecode, self.example[::-1]) 576 self.assertEqual( 577 a, 578 array.array(self.typecode, self.example + self.example[::-1]) 579 ) 580 581 b = array.array(self.badtypecode()) 582 self.assertRaises(TypeError, a.__add__, b) 583 584 self.assertRaises(TypeError, a.__add__, "bad") 585 586 def test_iadd(self): 587 a = array.array(self.typecode, self.example[::-1]) 588 b = a 589 a += array.array(self.typecode, 2*self.example) 590 self.assertIs(a, b) 591 self.assertEqual( 592 a, 593 array.array(self.typecode, self.example[::-1]+2*self.example) 594 ) 595 a = array.array(self.typecode, self.example) 596 a += a 597 self.assertEqual( 598 a, 599 array.array(self.typecode, self.example + self.example) 600 ) 601 602 b = array.array(self.badtypecode()) 603 self.assertRaises(TypeError, a.__add__, b) 604 605 self.assertRaises(TypeError, a.__iadd__, "bad") 606 607 def test_mul(self): 608 a = 5*array.array(self.typecode, self.example) 609 self.assertEqual( 610 a, 611 array.array(self.typecode, 5*self.example) 612 ) 613 614 a = array.array(self.typecode, self.example)*5 615 self.assertEqual( 616 a, 617 array.array(self.typecode, self.example*5) 618 ) 619 620 a = 0*array.array(self.typecode, self.example) 621 self.assertEqual( 622 a, 623 array.array(self.typecode) 624 ) 625 626 a = (-1)*array.array(self.typecode, self.example) 627 self.assertEqual( 628 a, 629 array.array(self.typecode) 630 ) 631 632 a = 5 * array.array(self.typecode, self.example[:1]) 633 self.assertEqual( 634 a, 635 array.array(self.typecode, [a[0]] * 5) 636 ) 637 638 self.assertRaises(TypeError, a.__mul__, "bad") 639 640 def test_imul(self): 641 a = array.array(self.typecode, self.example) 642 b = a 643 644 a *= 5 645 self.assertIs(a, b) 646 self.assertEqual( 647 a, 648 array.array(self.typecode, 5*self.example) 649 ) 650 651 a *= 0 652 self.assertIs(a, b) 653 self.assertEqual(a, array.array(self.typecode)) 654 655 a *= 1000 656 self.assertIs(a, b) 657 self.assertEqual(a, array.array(self.typecode)) 658 659 a *= -1 660 self.assertIs(a, b) 661 self.assertEqual(a, array.array(self.typecode)) 662 663 a = array.array(self.typecode, self.example) 664 a *= -1 665 self.assertEqual(a, array.array(self.typecode)) 666 667 self.assertRaises(TypeError, a.__imul__, "bad") 668 669 def test_getitem(self): 670 a = array.array(self.typecode, self.example) 671 self.assertEntryEqual(a[0], self.example[0]) 672 self.assertEntryEqual(a[0], self.example[0]) 673 self.assertEntryEqual(a[-1], self.example[-1]) 674 self.assertEntryEqual(a[-1], self.example[-1]) 675 self.assertEntryEqual(a[len(self.example)-1], self.example[-1]) 676 self.assertEntryEqual(a[-len(self.example)], self.example[0]) 677 self.assertRaises(TypeError, a.__getitem__) 678 self.assertRaises(IndexError, a.__getitem__, len(self.example)) 679 self.assertRaises(IndexError, a.__getitem__, -len(self.example)-1) 680 681 def test_setitem(self): 682 a = array.array(self.typecode, self.example) 683 a[0] = a[-1] 684 self.assertEntryEqual(a[0], a[-1]) 685 686 a = array.array(self.typecode, self.example) 687 a[0] = a[-1] 688 self.assertEntryEqual(a[0], a[-1]) 689 690 a = array.array(self.typecode, self.example) 691 a[-1] = a[0] 692 self.assertEntryEqual(a[0], a[-1]) 693 694 a = array.array(self.typecode, self.example) 695 a[-1] = a[0] 696 self.assertEntryEqual(a[0], a[-1]) 697 698 a = array.array(self.typecode, self.example) 699 a[len(self.example)-1] = a[0] 700 self.assertEntryEqual(a[0], a[-1]) 701 702 a = array.array(self.typecode, self.example) 703 a[-len(self.example)] = a[-1] 704 self.assertEntryEqual(a[0], a[-1]) 705 706 self.assertRaises(TypeError, a.__setitem__) 707 self.assertRaises(TypeError, a.__setitem__, None) 708 self.assertRaises(TypeError, a.__setitem__, 0, None) 709 self.assertRaises( 710 IndexError, 711 a.__setitem__, 712 len(self.example), self.example[0] 713 ) 714 self.assertRaises( 715 IndexError, 716 a.__setitem__, 717 -len(self.example)-1, self.example[0] 718 ) 719 720 def test_delitem(self): 721 a = array.array(self.typecode, self.example) 722 del a[0] 723 self.assertEqual( 724 a, 725 array.array(self.typecode, self.example[1:]) 726 ) 727 728 a = array.array(self.typecode, self.example) 729 del a[-1] 730 self.assertEqual( 731 a, 732 array.array(self.typecode, self.example[:-1]) 733 ) 734 735 a = array.array(self.typecode, self.example) 736 del a[len(self.example)-1] 737 self.assertEqual( 738 a, 739 array.array(self.typecode, self.example[:-1]) 740 ) 741 742 a = array.array(self.typecode, self.example) 743 del a[-len(self.example)] 744 self.assertEqual( 745 a, 746 array.array(self.typecode, self.example[1:]) 747 ) 748 749 self.assertRaises(TypeError, a.__delitem__) 750 self.assertRaises(TypeError, a.__delitem__, None) 751 self.assertRaises(IndexError, a.__delitem__, len(self.example)) 752 self.assertRaises(IndexError, a.__delitem__, -len(self.example)-1) 753 754 def test_getslice(self): 755 a = array.array(self.typecode, self.example) 756 self.assertEqual(a[:], a) 757 758 self.assertEqual( 759 a[1:], 760 array.array(self.typecode, self.example[1:]) 761 ) 762 763 self.assertEqual( 764 a[:1], 765 array.array(self.typecode, self.example[:1]) 766 ) 767 768 self.assertEqual( 769 a[:-1], 770 array.array(self.typecode, self.example[:-1]) 771 ) 772 773 self.assertEqual( 774 a[-1:], 775 array.array(self.typecode, self.example[-1:]) 776 ) 777 778 self.assertEqual( 779 a[-1:-1], 780 array.array(self.typecode) 781 ) 782 783 self.assertEqual( 784 a[2:1], 785 array.array(self.typecode) 786 ) 787 788 self.assertEqual( 789 a[1000:], 790 array.array(self.typecode) 791 ) 792 self.assertEqual(a[-1000:], a) 793 self.assertEqual(a[:1000], a) 794 self.assertEqual( 795 a[:-1000], 796 array.array(self.typecode) 797 ) 798 self.assertEqual(a[-1000:1000], a) 799 self.assertEqual( 800 a[2000:1000], 801 array.array(self.typecode) 802 ) 803 804 def test_extended_getslice(self): 805 # Test extended slicing by comparing with list slicing 806 # (Assumes list conversion works correctly, too) 807 a = array.array(self.typecode, self.example) 808 indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100) 809 for start in indices: 810 for stop in indices: 811 # Everything except the initial 0 (invalid step) 812 for step in indices[1:]: 813 self.assertEqual(list(a[start:stop:step]), 814 list(a)[start:stop:step]) 815 816 def test_setslice(self): 817 a = array.array(self.typecode, self.example) 818 a[:1] = a 819 self.assertEqual( 820 a, 821 array.array(self.typecode, self.example + self.example[1:]) 822 ) 823 824 a = array.array(self.typecode, self.example) 825 a[:-1] = a 826 self.assertEqual( 827 a, 828 array.array(self.typecode, self.example + self.example[-1:]) 829 ) 830 831 a = array.array(self.typecode, self.example) 832 a[-1:] = a 833 self.assertEqual( 834 a, 835 array.array(self.typecode, self.example[:-1] + self.example) 836 ) 837 838 a = array.array(self.typecode, self.example) 839 a[1:] = a 840 self.assertEqual( 841 a, 842 array.array(self.typecode, self.example[:1] + self.example) 843 ) 844 845 a = array.array(self.typecode, self.example) 846 a[1:-1] = a 847 self.assertEqual( 848 a, 849 array.array( 850 self.typecode, 851 self.example[:1] + self.example + self.example[-1:] 852 ) 853 ) 854 855 a = array.array(self.typecode, self.example) 856 a[1000:] = a 857 self.assertEqual( 858 a, 859 array.array(self.typecode, 2*self.example) 860 ) 861 862 a = array.array(self.typecode, self.example) 863 a[-1000:] = a 864 self.assertEqual( 865 a, 866 array.array(self.typecode, self.example) 867 ) 868 869 a = array.array(self.typecode, self.example) 870 a[:1000] = a 871 self.assertEqual( 872 a, 873 array.array(self.typecode, self.example) 874 ) 875 876 a = array.array(self.typecode, self.example) 877 a[:-1000] = a 878 self.assertEqual( 879 a, 880 array.array(self.typecode, 2*self.example) 881 ) 882 883 a = array.array(self.typecode, self.example) 884 a[1:0] = a 885 self.assertEqual( 886 a, 887 array.array(self.typecode, self.example[:1] + self.example + self.example[1:]) 888 ) 889 890 a = array.array(self.typecode, self.example) 891 a[2000:1000] = a 892 self.assertEqual( 893 a, 894 array.array(self.typecode, 2*self.example) 895 ) 896 897 a = array.array(self.typecode, self.example) 898 self.assertRaises(TypeError, a.__setitem__, slice(0, 0), None) 899 self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None) 900 901 b = array.array(self.badtypecode()) 902 self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b) 903 self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b) 904 905 def test_extended_set_del_slice(self): 906 indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100) 907 for start in indices: 908 for stop in indices: 909 # Everything except the initial 0 (invalid step) 910 for step in indices[1:]: 911 a = array.array(self.typecode, self.example) 912 L = list(a) 913 # Make sure we have a slice of exactly the right length, 914 # but with (hopefully) different data. 915 data = L[start:stop:step] 916 data.reverse() 917 L[start:stop:step] = data 918 a[start:stop:step] = array.array(self.typecode, data) 919 self.assertEqual(a, array.array(self.typecode, L)) 920 921 del L[start:stop:step] 922 del a[start:stop:step] 923 self.assertEqual(a, array.array(self.typecode, L)) 924 925 def test_index(self): 926 example = 2*self.example 927 a = array.array(self.typecode, example) 928 self.assertRaises(TypeError, a.index) 929 for x in example: 930 self.assertEqual(a.index(x), example.index(x)) 931 self.assertRaises(ValueError, a.index, None) 932 self.assertRaises(ValueError, a.index, self.outside) 933 934 a = array.array('i', [-2, -1, 0, 0, 1, 2]) 935 self.assertEqual(a.index(0), 2) 936 self.assertEqual(a.index(0, 2), 2) 937 self.assertEqual(a.index(0, -4), 2) 938 self.assertEqual(a.index(-2, -10), 0) 939 self.assertEqual(a.index(0, 3), 3) 940 self.assertEqual(a.index(0, -3), 3) 941 self.assertEqual(a.index(0, 3, 4), 3) 942 self.assertEqual(a.index(0, -3, -2), 3) 943 self.assertRaises(ValueError, a.index, 2, 0, -10) 944 945 def test_count(self): 946 example = 2*self.example 947 a = array.array(self.typecode, example) 948 self.assertRaises(TypeError, a.count) 949 for x in example: 950 self.assertEqual(a.count(x), example.count(x)) 951 self.assertEqual(a.count(self.outside), 0) 952 self.assertEqual(a.count(None), 0) 953 954 def test_remove(self): 955 for x in self.example: 956 example = 2*self.example 957 a = array.array(self.typecode, example) 958 pos = example.index(x) 959 example2 = example[:pos] + example[pos+1:] 960 a.remove(x) 961 self.assertEqual(a, array.array(self.typecode, example2)) 962 963 a = array.array(self.typecode, self.example) 964 self.assertRaises(ValueError, a.remove, self.outside) 965 966 self.assertRaises(ValueError, a.remove, None) 967 968 def test_pop(self): 969 a = array.array(self.typecode) 970 self.assertRaises(IndexError, a.pop) 971 972 a = array.array(self.typecode, 2*self.example) 973 self.assertRaises(TypeError, a.pop, 42, 42) 974 self.assertRaises(TypeError, a.pop, None) 975 self.assertRaises(IndexError, a.pop, len(a)) 976 self.assertRaises(IndexError, a.pop, -len(a)-1) 977 978 self.assertEntryEqual(a.pop(0), self.example[0]) 979 self.assertEqual( 980 a, 981 array.array(self.typecode, self.example[1:]+self.example) 982 ) 983 self.assertEntryEqual(a.pop(1), self.example[2]) 984 self.assertEqual( 985 a, 986 array.array(self.typecode, self.example[1:2]+self.example[3:]+self.example) 987 ) 988 self.assertEntryEqual(a.pop(0), self.example[1]) 989 self.assertEntryEqual(a.pop(), self.example[-1]) 990 self.assertEqual( 991 a, 992 array.array(self.typecode, self.example[3:]+self.example[:-1]) 993 ) 994 995 def test_reverse(self): 996 a = array.array(self.typecode, self.example) 997 self.assertRaises(TypeError, a.reverse, 42) 998 a.reverse() 999 self.assertEqual( 1000 a, 1001 array.array(self.typecode, self.example[::-1]) 1002 ) 1003 1004 def test_extend(self): 1005 a = array.array(self.typecode, self.example) 1006 self.assertRaises(TypeError, a.extend) 1007 a.extend(array.array(self.typecode, self.example[::-1])) 1008 self.assertEqual( 1009 a, 1010 array.array(self.typecode, self.example+self.example[::-1]) 1011 ) 1012 1013 a = array.array(self.typecode, self.example) 1014 a.extend(a) 1015 self.assertEqual( 1016 a, 1017 array.array(self.typecode, self.example+self.example) 1018 ) 1019 1020 b = array.array(self.badtypecode()) 1021 self.assertRaises(TypeError, a.extend, b) 1022 1023 a = array.array(self.typecode, self.example) 1024 a.extend(self.example[::-1]) 1025 self.assertEqual( 1026 a, 1027 array.array(self.typecode, self.example+self.example[::-1]) 1028 ) 1029 1030 def test_constructor_with_iterable_argument(self): 1031 a = array.array(self.typecode, iter(self.example)) 1032 b = array.array(self.typecode, self.example) 1033 self.assertEqual(a, b) 1034 1035 # non-iterable argument 1036 self.assertRaises(TypeError, array.array, self.typecode, 10) 1037 1038 # pass through errors raised in __iter__ 1039 class A: 1040 def __iter__(self): 1041 raise UnicodeError 1042 self.assertRaises(UnicodeError, array.array, self.typecode, A()) 1043 1044 # pass through errors raised in next() 1045 def B(): 1046 raise UnicodeError 1047 yield None 1048 self.assertRaises(UnicodeError, array.array, self.typecode, B()) 1049 1050 def test_coveritertraverse(self): 1051 try: 1052 import gc 1053 except ImportError: 1054 self.skipTest('gc module not available') 1055 a = array.array(self.typecode) 1056 l = [iter(a)] 1057 l.append(l) 1058 gc.collect() 1059 1060 def test_buffer(self): 1061 a = array.array(self.typecode, self.example) 1062 m = memoryview(a) 1063 expected = m.tobytes() 1064 self.assertEqual(a.tobytes(), expected) 1065 self.assertEqual(a.tobytes()[0], expected[0]) 1066 # Resizing is forbidden when there are buffer exports. 1067 # For issue 4509, we also check after each error that 1068 # the array was not modified. 1069 self.assertRaises(BufferError, a.append, a[0]) 1070 self.assertEqual(m.tobytes(), expected) 1071 self.assertRaises(BufferError, a.extend, a[0:1]) 1072 self.assertEqual(m.tobytes(), expected) 1073 self.assertRaises(BufferError, a.remove, a[0]) 1074 self.assertEqual(m.tobytes(), expected) 1075 self.assertRaises(BufferError, a.pop, 0) 1076 self.assertEqual(m.tobytes(), expected) 1077 self.assertRaises(BufferError, a.fromlist, a.tolist()) 1078 self.assertEqual(m.tobytes(), expected) 1079 self.assertRaises(BufferError, a.frombytes, a.tobytes()) 1080 self.assertEqual(m.tobytes(), expected) 1081 if self.typecode == 'u': 1082 self.assertRaises(BufferError, a.fromunicode, a.tounicode()) 1083 self.assertEqual(m.tobytes(), expected) 1084 self.assertRaises(BufferError, operator.imul, a, 2) 1085 self.assertEqual(m.tobytes(), expected) 1086 self.assertRaises(BufferError, operator.imul, a, 0) 1087 self.assertEqual(m.tobytes(), expected) 1088 self.assertRaises(BufferError, operator.setitem, a, slice(0, 0), a) 1089 self.assertEqual(m.tobytes(), expected) 1090 self.assertRaises(BufferError, operator.delitem, a, 0) 1091 self.assertEqual(m.tobytes(), expected) 1092 self.assertRaises(BufferError, operator.delitem, a, slice(0, 1)) 1093 self.assertEqual(m.tobytes(), expected) 1094 1095 def test_weakref(self): 1096 s = array.array(self.typecode, self.example) 1097 p = weakref.proxy(s) 1098 self.assertEqual(p.tobytes(), s.tobytes()) 1099 s = None 1100 support.gc_collect() # For PyPy or other GCs. 1101 self.assertRaises(ReferenceError, len, p) 1102 1103 @unittest.skipUnless(hasattr(sys, 'getrefcount'), 1104 'test needs sys.getrefcount()') 1105 def test_bug_782369(self): 1106 for i in range(10): 1107 b = array.array('B', range(64)) 1108 rc = sys.getrefcount(10) 1109 for i in range(10): 1110 b = array.array('B', range(64)) 1111 self.assertEqual(rc, sys.getrefcount(10)) 1112 1113 def test_subclass_with_kwargs(self): 1114 # SF bug #1486663 -- this used to erroneously raise a TypeError 1115 ArraySubclassWithKwargs('b', newarg=1) 1116 1117 def test_create_from_bytes(self): 1118 # XXX This test probably needs to be moved in a subclass or 1119 # generalized to use self.typecode. 1120 a = array.array('H', b"1234") 1121 self.assertEqual(len(a) * a.itemsize, 4) 1122 1123 @support.cpython_only 1124 def test_sizeof_with_buffer(self): 1125 a = array.array(self.typecode, self.example) 1126 basesize = support.calcvobjsize('Pn2Pi') 1127 buffer_size = a.buffer_info()[1] * a.itemsize 1128 support.check_sizeof(self, a, basesize + buffer_size) 1129 1130 @support.cpython_only 1131 def test_sizeof_without_buffer(self): 1132 a = array.array(self.typecode) 1133 basesize = support.calcvobjsize('Pn2Pi') 1134 support.check_sizeof(self, a, basesize) 1135 1136 def test_initialize_with_unicode(self): 1137 if self.typecode != 'u': 1138 with self.assertRaises(TypeError) as cm: 1139 a = array.array(self.typecode, 'foo') 1140 self.assertIn("cannot use a str", str(cm.exception)) 1141 with self.assertRaises(TypeError) as cm: 1142 a = array.array(self.typecode, array.array('u', 'foo')) 1143 self.assertIn("cannot use a unicode array", str(cm.exception)) 1144 else: 1145 a = array.array(self.typecode, "foo") 1146 a = array.array(self.typecode, array.array('u', 'foo')) 1147 1148 @support.cpython_only 1149 def test_obsolete_write_lock(self): 1150 from _testcapi import getbuffer_with_null_view 1151 a = array.array('B', b"") 1152 self.assertRaises(BufferError, getbuffer_with_null_view, a) 1153 1154 def test_free_after_iterating(self): 1155 support.check_free_after_iterating(self, iter, array.array, 1156 (self.typecode,)) 1157 support.check_free_after_iterating(self, reversed, array.array, 1158 (self.typecode,)) 1159 1160class StringTest(BaseTest): 1161 1162 def test_setitem(self): 1163 super().test_setitem() 1164 a = array.array(self.typecode, self.example) 1165 self.assertRaises(TypeError, a.__setitem__, 0, self.example[:2]) 1166 1167class UnicodeTest(StringTest, unittest.TestCase): 1168 typecode = 'u' 1169 example = '\x01\u263a\x00\ufeff' 1170 smallerexample = '\x01\u263a\x00\ufefe' 1171 biggerexample = '\x01\u263a\x01\ufeff' 1172 outside = str('\x33') 1173 minitemsize = 2 1174 1175 def test_unicode(self): 1176 self.assertRaises(TypeError, array.array, 'b', 'foo') 1177 1178 a = array.array('u', '\xa0\xc2\u1234') 1179 a.fromunicode(' ') 1180 a.fromunicode('') 1181 a.fromunicode('') 1182 a.fromunicode('\x11abc\xff\u1234') 1183 s = a.tounicode() 1184 self.assertEqual(s, '\xa0\xc2\u1234 \x11abc\xff\u1234') 1185 self.assertEqual(a.itemsize, sizeof_wchar) 1186 1187 s = '\x00="\'a\\b\x80\xff\u0000\u0001\u1234' 1188 a = array.array('u', s) 1189 self.assertEqual( 1190 repr(a), 1191 "array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')") 1192 1193 self.assertRaises(TypeError, a.fromunicode) 1194 1195 def test_issue17223(self): 1196 # this used to crash 1197 if sizeof_wchar == 4: 1198 # U+FFFFFFFF is an invalid code point in Unicode 6.0 1199 invalid_str = b'\xff\xff\xff\xff' 1200 else: 1201 # PyUnicode_FromUnicode() cannot fail with 16-bit wchar_t 1202 self.skipTest("specific to 32-bit wchar_t") 1203 a = array.array('u', invalid_str) 1204 self.assertRaises(ValueError, a.tounicode) 1205 self.assertRaises(ValueError, str, a) 1206 1207class NumberTest(BaseTest): 1208 1209 def test_extslice(self): 1210 a = array.array(self.typecode, range(5)) 1211 self.assertEqual(a[::], a) 1212 self.assertEqual(a[::2], array.array(self.typecode, [0,2,4])) 1213 self.assertEqual(a[1::2], array.array(self.typecode, [1,3])) 1214 self.assertEqual(a[::-1], array.array(self.typecode, [4,3,2,1,0])) 1215 self.assertEqual(a[::-2], array.array(self.typecode, [4,2,0])) 1216 self.assertEqual(a[3::-2], array.array(self.typecode, [3,1])) 1217 self.assertEqual(a[-100:100:], a) 1218 self.assertEqual(a[100:-100:-1], a[::-1]) 1219 self.assertEqual(a[-100:100:2], array.array(self.typecode, [0,2,4])) 1220 self.assertEqual(a[1000:2000:2], array.array(self.typecode, [])) 1221 self.assertEqual(a[-1000:-2000:-2], array.array(self.typecode, [])) 1222 1223 def test_delslice(self): 1224 a = array.array(self.typecode, range(5)) 1225 del a[::2] 1226 self.assertEqual(a, array.array(self.typecode, [1,3])) 1227 a = array.array(self.typecode, range(5)) 1228 del a[1::2] 1229 self.assertEqual(a, array.array(self.typecode, [0,2,4])) 1230 a = array.array(self.typecode, range(5)) 1231 del a[1::-2] 1232 self.assertEqual(a, array.array(self.typecode, [0,2,3,4])) 1233 a = array.array(self.typecode, range(10)) 1234 del a[::1000] 1235 self.assertEqual(a, array.array(self.typecode, [1,2,3,4,5,6,7,8,9])) 1236 # test issue7788 1237 a = array.array(self.typecode, range(10)) 1238 del a[9::1<<333] 1239 1240 def test_assignment(self): 1241 a = array.array(self.typecode, range(10)) 1242 a[::2] = array.array(self.typecode, [42]*5) 1243 self.assertEqual(a, array.array(self.typecode, [42, 1, 42, 3, 42, 5, 42, 7, 42, 9])) 1244 a = array.array(self.typecode, range(10)) 1245 a[::-4] = array.array(self.typecode, [10]*3) 1246 self.assertEqual(a, array.array(self.typecode, [0, 10, 2, 3, 4, 10, 6, 7, 8 ,10])) 1247 a = array.array(self.typecode, range(4)) 1248 a[::-1] = a 1249 self.assertEqual(a, array.array(self.typecode, [3, 2, 1, 0])) 1250 a = array.array(self.typecode, range(10)) 1251 b = a[:] 1252 c = a[:] 1253 ins = array.array(self.typecode, range(2)) 1254 a[2:3] = ins 1255 b[slice(2,3)] = ins 1256 c[2:3:] = ins 1257 1258 def test_iterationcontains(self): 1259 a = array.array(self.typecode, range(10)) 1260 self.assertEqual(list(a), list(range(10))) 1261 b = array.array(self.typecode, [20]) 1262 self.assertEqual(a[-1] in a, True) 1263 self.assertEqual(b[0] not in a, True) 1264 1265 def check_overflow(self, lower, upper): 1266 # method to be used by subclasses 1267 1268 # should not overflow assigning lower limit 1269 a = array.array(self.typecode, [lower]) 1270 a[0] = lower 1271 # should overflow assigning less than lower limit 1272 self.assertRaises(OverflowError, array.array, self.typecode, [lower-1]) 1273 self.assertRaises(OverflowError, a.__setitem__, 0, lower-1) 1274 # should not overflow assigning upper limit 1275 a = array.array(self.typecode, [upper]) 1276 a[0] = upper 1277 # should overflow assigning more than upper limit 1278 self.assertRaises(OverflowError, array.array, self.typecode, [upper+1]) 1279 self.assertRaises(OverflowError, a.__setitem__, 0, upper+1) 1280 1281 def test_subclassing(self): 1282 typecode = self.typecode 1283 class ExaggeratingArray(array.array): 1284 __slots__ = ['offset'] 1285 1286 def __new__(cls, typecode, data, offset): 1287 return array.array.__new__(cls, typecode, data) 1288 1289 def __init__(self, typecode, data, offset): 1290 self.offset = offset 1291 1292 def __getitem__(self, i): 1293 return array.array.__getitem__(self, i) + self.offset 1294 1295 a = ExaggeratingArray(self.typecode, [3, 6, 7, 11], 4) 1296 self.assertEntryEqual(a[0], 7) 1297 1298 self.assertRaises(AttributeError, setattr, a, "color", "blue") 1299 1300 def test_frombytearray(self): 1301 a = array.array('b', range(10)) 1302 b = array.array(self.typecode, a) 1303 self.assertEqual(a, b) 1304 1305class IntegerNumberTest(NumberTest): 1306 def test_type_error(self): 1307 a = array.array(self.typecode) 1308 a.append(42) 1309 with self.assertRaises(TypeError): 1310 a.append(42.0) 1311 with self.assertRaises(TypeError): 1312 a[0] = 42.0 1313 1314class Intable: 1315 def __init__(self, num): 1316 self._num = num 1317 def __index__(self): 1318 return self._num 1319 def __int__(self): 1320 return self._num 1321 def __sub__(self, other): 1322 return Intable(int(self) - int(other)) 1323 def __add__(self, other): 1324 return Intable(int(self) + int(other)) 1325 1326class SignedNumberTest(IntegerNumberTest): 1327 example = [-1, 0, 1, 42, 0x7f] 1328 smallerexample = [-1, 0, 1, 42, 0x7e] 1329 biggerexample = [-1, 0, 1, 43, 0x7f] 1330 outside = 23 1331 1332 def test_overflow(self): 1333 a = array.array(self.typecode) 1334 lower = -1 * int(pow(2, a.itemsize * 8 - 1)) 1335 upper = int(pow(2, a.itemsize * 8 - 1)) - 1 1336 self.check_overflow(lower, upper) 1337 self.check_overflow(Intable(lower), Intable(upper)) 1338 1339class UnsignedNumberTest(IntegerNumberTest): 1340 example = [0, 1, 17, 23, 42, 0xff] 1341 smallerexample = [0, 1, 17, 23, 42, 0xfe] 1342 biggerexample = [0, 1, 17, 23, 43, 0xff] 1343 outside = 0xaa 1344 1345 def test_overflow(self): 1346 a = array.array(self.typecode) 1347 lower = 0 1348 upper = int(pow(2, a.itemsize * 8)) - 1 1349 self.check_overflow(lower, upper) 1350 self.check_overflow(Intable(lower), Intable(upper)) 1351 1352 def test_bytes_extend(self): 1353 s = bytes(self.example) 1354 1355 a = array.array(self.typecode, self.example) 1356 a.extend(s) 1357 self.assertEqual( 1358 a, 1359 array.array(self.typecode, self.example+self.example) 1360 ) 1361 1362 a = array.array(self.typecode, self.example) 1363 a.extend(bytearray(reversed(s))) 1364 self.assertEqual( 1365 a, 1366 array.array(self.typecode, self.example+self.example[::-1]) 1367 ) 1368 1369 1370class ByteTest(SignedNumberTest, unittest.TestCase): 1371 typecode = 'b' 1372 minitemsize = 1 1373 1374class UnsignedByteTest(UnsignedNumberTest, unittest.TestCase): 1375 typecode = 'B' 1376 minitemsize = 1 1377 1378class ShortTest(SignedNumberTest, unittest.TestCase): 1379 typecode = 'h' 1380 minitemsize = 2 1381 1382class UnsignedShortTest(UnsignedNumberTest, unittest.TestCase): 1383 typecode = 'H' 1384 minitemsize = 2 1385 1386class IntTest(SignedNumberTest, unittest.TestCase): 1387 typecode = 'i' 1388 minitemsize = 2 1389 1390class UnsignedIntTest(UnsignedNumberTest, unittest.TestCase): 1391 typecode = 'I' 1392 minitemsize = 2 1393 1394class LongTest(SignedNumberTest, unittest.TestCase): 1395 typecode = 'l' 1396 minitemsize = 4 1397 1398class UnsignedLongTest(UnsignedNumberTest, unittest.TestCase): 1399 typecode = 'L' 1400 minitemsize = 4 1401 1402class LongLongTest(SignedNumberTest, unittest.TestCase): 1403 typecode = 'q' 1404 minitemsize = 8 1405 1406class UnsignedLongLongTest(UnsignedNumberTest, unittest.TestCase): 1407 typecode = 'Q' 1408 minitemsize = 8 1409 1410class FPTest(NumberTest): 1411 example = [-42.0, 0, 42, 1e5, -1e10] 1412 smallerexample = [-42.0, 0, 42, 1e5, -2e10] 1413 biggerexample = [-42.0, 0, 42, 1e5, 1e10] 1414 outside = 23 1415 1416 def assertEntryEqual(self, entry1, entry2): 1417 self.assertAlmostEqual(entry1, entry2) 1418 1419 def test_nan(self): 1420 a = array.array(self.typecode, [float('nan')]) 1421 b = array.array(self.typecode, [float('nan')]) 1422 self.assertIs(a != b, True) 1423 self.assertIs(a == b, False) 1424 self.assertIs(a > b, False) 1425 self.assertIs(a >= b, False) 1426 self.assertIs(a < b, False) 1427 self.assertIs(a <= b, False) 1428 1429 def test_byteswap(self): 1430 a = array.array(self.typecode, self.example) 1431 self.assertRaises(TypeError, a.byteswap, 42) 1432 if a.itemsize in (1, 2, 4, 8): 1433 b = array.array(self.typecode, self.example) 1434 b.byteswap() 1435 if a.itemsize==1: 1436 self.assertEqual(a, b) 1437 else: 1438 # On alphas treating the byte swapped bit patters as 1439 # floats/doubles results in floating point exceptions 1440 # => compare the 8bit string values instead 1441 self.assertNotEqual(a.tobytes(), b.tobytes()) 1442 b.byteswap() 1443 self.assertEqual(a, b) 1444 1445class FloatTest(FPTest, unittest.TestCase): 1446 typecode = 'f' 1447 minitemsize = 4 1448 1449class DoubleTest(FPTest, unittest.TestCase): 1450 typecode = 'd' 1451 minitemsize = 8 1452 1453 def test_alloc_overflow(self): 1454 from sys import maxsize 1455 a = array.array('d', [-1]*65536) 1456 try: 1457 a *= maxsize//65536 + 1 1458 except MemoryError: 1459 pass 1460 else: 1461 self.fail("Array of size > maxsize created - MemoryError expected") 1462 b = array.array('d', [ 2.71828183, 3.14159265, -1]) 1463 try: 1464 b * (maxsize//3 + 1) 1465 except MemoryError: 1466 pass 1467 else: 1468 self.fail("Array of size > maxsize created - MemoryError expected") 1469 1470 1471class LargeArrayTest(unittest.TestCase): 1472 typecode = 'b' 1473 1474 def example(self, size): 1475 # We assess a base memuse of <=2.125 for constructing this array 1476 base = array.array(self.typecode, [0, 1, 2, 3, 4, 5, 6, 7]) * (size // 8) 1477 base += array.array(self.typecode, [99]*(size % 8) + [8, 9, 10, 11]) 1478 return base 1479 1480 @support.bigmemtest(_2G, memuse=2.125) 1481 def test_example_data(self, size): 1482 example = self.example(size) 1483 self.assertEqual(len(example), size+4) 1484 1485 @support.bigmemtest(_2G, memuse=2.125) 1486 def test_access(self, size): 1487 example = self.example(size) 1488 self.assertEqual(example[0], 0) 1489 self.assertEqual(example[-(size+4)], 0) 1490 self.assertEqual(example[size], 8) 1491 self.assertEqual(example[-4], 8) 1492 self.assertEqual(example[size+3], 11) 1493 self.assertEqual(example[-1], 11) 1494 1495 @support.bigmemtest(_2G, memuse=2.125+1) 1496 def test_slice(self, size): 1497 example = self.example(size) 1498 self.assertEqual(list(example[:4]), [0, 1, 2, 3]) 1499 self.assertEqual(list(example[-4:]), [8, 9, 10, 11]) 1500 part = example[1:-1] 1501 self.assertEqual(len(part), size+2) 1502 self.assertEqual(part[0], 1) 1503 self.assertEqual(part[-1], 10) 1504 del part 1505 part = example[::2] 1506 self.assertEqual(len(part), (size+5)//2) 1507 self.assertEqual(list(part[:4]), [0, 2, 4, 6]) 1508 if size % 2: 1509 self.assertEqual(list(part[-2:]), [9, 11]) 1510 else: 1511 self.assertEqual(list(part[-2:]), [8, 10]) 1512 1513 @support.bigmemtest(_2G, memuse=2.125) 1514 def test_count(self, size): 1515 example = self.example(size) 1516 self.assertEqual(example.count(0), size//8) 1517 self.assertEqual(example.count(11), 1) 1518 1519 @support.bigmemtest(_2G, memuse=2.125) 1520 def test_append(self, size): 1521 example = self.example(size) 1522 example.append(12) 1523 self.assertEqual(example[-1], 12) 1524 1525 @support.bigmemtest(_2G, memuse=2.125) 1526 def test_extend(self, size): 1527 example = self.example(size) 1528 example.extend(iter([12, 13, 14, 15])) 1529 self.assertEqual(len(example), size+8) 1530 self.assertEqual(list(example[-8:]), [8, 9, 10, 11, 12, 13, 14, 15]) 1531 1532 @support.bigmemtest(_2G, memuse=2.125) 1533 def test_frombytes(self, size): 1534 example = self.example(size) 1535 example.frombytes(b'abcd') 1536 self.assertEqual(len(example), size+8) 1537 self.assertEqual(list(example[-8:]), [8, 9, 10, 11] + list(b'abcd')) 1538 1539 @support.bigmemtest(_2G, memuse=2.125) 1540 def test_fromlist(self, size): 1541 example = self.example(size) 1542 example.fromlist([12, 13, 14, 15]) 1543 self.assertEqual(len(example), size+8) 1544 self.assertEqual(list(example[-8:]), [8, 9, 10, 11, 12, 13, 14, 15]) 1545 1546 @support.bigmemtest(_2G, memuse=2.125) 1547 def test_index(self, size): 1548 example = self.example(size) 1549 self.assertEqual(example.index(0), 0) 1550 self.assertEqual(example.index(1), 1) 1551 self.assertEqual(example.index(7), 7) 1552 self.assertEqual(example.index(11), size+3) 1553 1554 @support.bigmemtest(_2G, memuse=2.125) 1555 def test_insert(self, size): 1556 example = self.example(size) 1557 example.insert(0, 12) 1558 example.insert(10, 13) 1559 example.insert(size+1, 14) 1560 self.assertEqual(len(example), size+7) 1561 self.assertEqual(example[0], 12) 1562 self.assertEqual(example[10], 13) 1563 self.assertEqual(example[size+1], 14) 1564 1565 @support.bigmemtest(_2G, memuse=2.125) 1566 def test_pop(self, size): 1567 example = self.example(size) 1568 self.assertEqual(example.pop(0), 0) 1569 self.assertEqual(example[0], 1) 1570 self.assertEqual(example.pop(size+1), 10) 1571 self.assertEqual(example[size+1], 11) 1572 self.assertEqual(example.pop(1), 2) 1573 self.assertEqual(example[1], 3) 1574 self.assertEqual(len(example), size+1) 1575 self.assertEqual(example.pop(), 11) 1576 self.assertEqual(len(example), size) 1577 1578 @support.bigmemtest(_2G, memuse=2.125) 1579 def test_remove(self, size): 1580 example = self.example(size) 1581 example.remove(0) 1582 self.assertEqual(len(example), size+3) 1583 self.assertEqual(example[0], 1) 1584 example.remove(10) 1585 self.assertEqual(len(example), size+2) 1586 self.assertEqual(example[size], 9) 1587 self.assertEqual(example[size+1], 11) 1588 1589 @support.bigmemtest(_2G, memuse=2.125) 1590 def test_reverse(self, size): 1591 example = self.example(size) 1592 example.reverse() 1593 self.assertEqual(len(example), size+4) 1594 self.assertEqual(example[0], 11) 1595 self.assertEqual(example[3], 8) 1596 self.assertEqual(example[-1], 0) 1597 example.reverse() 1598 self.assertEqual(len(example), size+4) 1599 self.assertEqual(list(example[:4]), [0, 1, 2, 3]) 1600 self.assertEqual(list(example[-4:]), [8, 9, 10, 11]) 1601 1602 # list takes about 9 bytes per element 1603 @support.bigmemtest(_2G, memuse=2.125+9) 1604 def test_tolist(self, size): 1605 example = self.example(size) 1606 ls = example.tolist() 1607 self.assertEqual(len(ls), len(example)) 1608 self.assertEqual(ls[:8], list(example[:8])) 1609 self.assertEqual(ls[-8:], list(example[-8:])) 1610 1611if __name__ == "__main__": 1612 unittest.main() 1613