|
37 | 37 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
38 | 38 | # SOFTWARE.
|
39 | 39 |
|
| 40 | +import unittest |
| 41 | +import sys |
| 42 | + |
| 43 | +import array |
| 44 | + |
40 | 45 | class _NamedIntConstant(int):
|
41 | 46 | def __new__(cls, value, name):
|
42 | 47 | self = super(_NamedIntConstant, cls).__new__(cls, value)
|
@@ -315,3 +320,244 @@ def __int__(self):
|
315 | 320 |
|
316 | 321 | def test_create_int_from_string():
|
317 | 322 | assert int("5c7920a80f5261a2e5322163c79b71a25a41f414", 16) == 527928385865769069253929759180846776123316630548
|
| 323 | + |
| 324 | + |
| 325 | +class FromBytesTests(unittest.TestCase): |
| 326 | + |
| 327 | + def check(self, tests, byteorder, signed=False): |
| 328 | + for test, expected in tests.items(): |
| 329 | + try: |
| 330 | + self.assertEqual( int.from_bytes(test, byteorder, signed=signed), expected) |
| 331 | + except Exception as err: |
| 332 | + raise AssertionError( |
| 333 | + "failed to convert {0} with byteorder={1!r} and signed={2}" |
| 334 | + .format(test, byteorder, signed)) from err |
| 335 | + |
| 336 | + def test_SignedBigEndian(self): |
| 337 | + # Convert signed big-endian byte arrays to integers. |
| 338 | + tests1 = { |
| 339 | + b'': 0, |
| 340 | + b'\x00': 0, |
| 341 | + b'\x00\x00': 0, |
| 342 | + b'\x01': 1, |
| 343 | + b'\x00\x01': 1, |
| 344 | + b'\xff': -1, |
| 345 | + b'\xff\xff': -1, |
| 346 | + b'\x81': -127, |
| 347 | + b'\x80': -128, |
| 348 | + b'\xff\x7f': -129, |
| 349 | + b'\x7f': 127, |
| 350 | + b'\x00\x81': 129, |
| 351 | + b'\xff\x01': -255, |
| 352 | + b'\xff\x00': -256, |
| 353 | + b'\x00\xff': 255, |
| 354 | + b'\x01\x00': 256, |
| 355 | + b'\x7f\xff': 32767, |
| 356 | + b'\x80\x00': -32768, |
| 357 | + b'\x00\xff\xff': 65535, |
| 358 | + b'\xff\x00\x00': -65536, |
| 359 | + b'\x80\x00\x00': -8388608 |
| 360 | + } |
| 361 | + self.check(tests1, 'big', signed=True) |
| 362 | + |
| 363 | + def test_SignedLittleEndian(self): |
| 364 | + # Convert signed little-endian byte arrays to integers. |
| 365 | + tests2 = { |
| 366 | + b'': 0, |
| 367 | + b'\x00': 0, |
| 368 | + b'\x00\x00': 0, |
| 369 | + b'\x01': 1, |
| 370 | + b'\x00\x01': 256, |
| 371 | + b'\xff': -1, |
| 372 | + b'\xff\xff': -1, |
| 373 | + b'\x81': -127, |
| 374 | + b'\x80': -128, |
| 375 | + b'\x7f\xff': -129, |
| 376 | + b'\x7f': 127, |
| 377 | + b'\x81\x00': 129, |
| 378 | + b'\x01\xff': -255, |
| 379 | + b'\x00\xff': -256, |
| 380 | + b'\xff\x00': 255, |
| 381 | + b'\x00\x01': 256, |
| 382 | + b'\xff\x7f': 32767, |
| 383 | + b'\x00\x80': -32768, |
| 384 | + b'\xff\xff\x00': 65535, |
| 385 | + b'\x00\x00\xff': -65536, |
| 386 | + b'\x00\x00\x80': -8388608 |
| 387 | + } |
| 388 | + self.check(tests2, 'little', signed=True) |
| 389 | + |
| 390 | + def test_UnsignedBigEndian(self): |
| 391 | + # Convert unsigned big-endian byte arrays to integers. |
| 392 | + tests3 = { |
| 393 | + b'': 0, |
| 394 | + b'\x00': 0, |
| 395 | + b'\x01': 1, |
| 396 | + b'\x7f': 127, |
| 397 | + b'\x80': 128, |
| 398 | + b'\xff': 255, |
| 399 | + b'\x01\x00': 256, |
| 400 | + b'\x7f\xff': 32767, |
| 401 | + b'\x80\x00': 32768, |
| 402 | + b'\xff\xff': 65535, |
| 403 | + b'\x01\x00\x00': 65536, |
| 404 | + } |
| 405 | + self.check(tests3, 'big', signed=False) |
| 406 | + |
| 407 | + def test_UnsignedLittleEndian(self): |
| 408 | + # Convert integers to unsigned little-endian byte arrays. |
| 409 | + tests4 = { |
| 410 | + b'': 0, |
| 411 | + b'\x00': 0, |
| 412 | + b'\x01': 1, |
| 413 | + b'\x7f': 127, |
| 414 | + b'\x80': 128, |
| 415 | + b'\xff': 255, |
| 416 | + b'\x00\x01': 256, |
| 417 | + b'\xff\x7f': 32767, |
| 418 | + b'\x00\x80': 32768, |
| 419 | + b'\xff\xff': 65535, |
| 420 | + b'\x00\x00\x01': 65536, |
| 421 | + } |
| 422 | + self.check(tests4, 'little', signed=False) |
| 423 | + |
| 424 | + def test_IntObject(self): |
| 425 | + myint = MyInt |
| 426 | + self.assertIs(type(myint.from_bytes(b'\x00', 'big')), MyInt) |
| 427 | + self.assertEqual(myint.from_bytes(b'\x01', 'big'), 1) |
| 428 | + self.assertIs( |
| 429 | + type(myint.from_bytes(b'\x00', 'big', signed=False)), myint) |
| 430 | + self.assertEqual(myint.from_bytes(b'\x01', 'big', signed=False), 1) |
| 431 | + self.assertIs(type(myint.from_bytes(b'\x00', 'little')), myint) |
| 432 | + self.assertEqual(myint.from_bytes(b'\x01', 'little'), 1) |
| 433 | + self.assertIs(type(myint.from_bytes( |
| 434 | + b'\x00', 'little', signed=False)), myint) |
| 435 | + self.assertEqual(myint.from_bytes(b'\x01', 'little', signed=False), 1) |
| 436 | + |
| 437 | + def test_from_list(self): |
| 438 | + self.assertEqual( |
| 439 | + int.from_bytes([255, 0, 0], 'big', signed=True), -65536) |
| 440 | + self.assertEqual( |
| 441 | + MyInt.from_bytes([255, 0, 0], 'big', signed=True), -65536) |
| 442 | + self.assertIs(type(MyInt.from_bytes( |
| 443 | + [255, 0, 0], 'little', signed=False)), MyInt) |
| 444 | + |
| 445 | + class LyingList(list): |
| 446 | + def __iter__(self): |
| 447 | + return iter([10, 20, 30, 40]) |
| 448 | + |
| 449 | + self.assertEqual( |
| 450 | + int.from_bytes(LyingList([255, 1, 1]), 'big'), 169090600) |
| 451 | + |
| 452 | + def test_from_tuple(self): |
| 453 | + self.assertEqual( |
| 454 | + int.from_bytes((255, 0, 0), 'big', signed=True), -65536) |
| 455 | + self.assertEqual( |
| 456 | + MyInt.from_bytes((255, 0, 0), 'big', signed=True), -65536) |
| 457 | + self.assertIs(type(MyInt.from_bytes( |
| 458 | + (255, 0, 0), 'little', signed=False)), MyInt) |
| 459 | + |
| 460 | + class LyingTuple(tuple): |
| 461 | + def __iter__(self): |
| 462 | + return iter((15, 25, 35, 45)) |
| 463 | + self.assertEqual( |
| 464 | + int.from_bytes(LyingTuple((255, 1, 1)), 'big'), 253305645) |
| 465 | + |
| 466 | + def test_from_bytearray(self): |
| 467 | + self.assertEqual(int.from_bytes( |
| 468 | + bytearray(b'\xff\x00\x00'), 'big', signed=True), -65536) |
| 469 | + self.assertEqual(int.from_bytes( |
| 470 | + bytearray(b'\xff\x00\x00'), 'big', signed=True), -65536) |
| 471 | + |
| 472 | + def test_from_array(self): |
| 473 | + self.assertEqual(int.from_bytes( |
| 474 | + array.array('b', b'\xff\x00\x00'), 'big', signed=True), -65536) |
| 475 | + |
| 476 | + ''' |
| 477 | + TODO This test is commented out until GR-12448 is not fixed. |
| 478 | + def test_from_memoryview(self): |
| 479 | + self.assertEqual(int.from_bytes( |
| 480 | + memoryview(b'\xff\x00\x00'), 'big', signed=True), -65536) |
| 481 | + ''' |
| 482 | + |
| 483 | + def test_wrong_input(self): |
| 484 | + self.assertRaises(ValueError, int.from_bytes, [256], 'big') |
| 485 | + self.assertRaises(ValueError, int.from_bytes, (256,), 'big') |
| 486 | + self.assertRaises(ValueError, int.from_bytes, [0], 'big\x00') |
| 487 | + self.assertRaises(ValueError, int.from_bytes, [0], 'little\x00') |
| 488 | + self.assertRaises(TypeError, int.from_bytes, 0, 'big') |
| 489 | + self.assertRaises(TypeError, int.from_bytes, 0, 'big', True) |
| 490 | + |
| 491 | + #TODO uncoment these tests, when GR-12453 is fixed |
| 492 | + #self.assertRaises(TypeError, int.from_bytes, "", 'big') |
| 493 | + #self.assertRaises(TypeError, int.from_bytes, "\x00", 'big') |
| 494 | + #self.assertRaises(TypeError, MyInt.from_bytes, "", 'big') |
| 495 | + #self.assertRaises(TypeError, MyInt.from_bytes, "\x00", 'big') |
| 496 | + self.assertRaises(TypeError, MyInt.from_bytes, 0, 'big') |
| 497 | + self.assertRaises(TypeError, int.from_bytes, 0, 'big', True) |
| 498 | + |
| 499 | + def test_int_subclass(self): |
| 500 | + class myint2(int): |
| 501 | + def __new__(cls, value): |
| 502 | + return int.__new__(cls, value + 1) |
| 503 | + |
| 504 | + i = myint2.from_bytes(b'\x01', 'big') |
| 505 | + self.assertIs(type(i), myint2) |
| 506 | + if (sys.version_info.major >= 3 and sys.version_info.minor >= 6): |
| 507 | + # It doesn't pass on old CPython |
| 508 | + self.assertEqual(i, 2) |
| 509 | + |
| 510 | + class myint3(int): |
| 511 | + def __init__(self, value): |
| 512 | + self.foo = 'bar' |
| 513 | + |
| 514 | + i = myint3.from_bytes(b'\x01', 'big') |
| 515 | + self.assertIs(type(i), myint3) |
| 516 | + self.assertEqual(i, 1) |
| 517 | + if (sys.version_info.major >= 3 and sys.version_info.minor >= 6): |
| 518 | + # It doesn't pass on old CPython |
| 519 | + self.assertEqual(getattr(i, 'foo', 'none'), 'bar') |
| 520 | + |
| 521 | + def test_range(self): |
| 522 | + self.assertEqual(int.from_bytes(range(5), 'big'), 16909060) |
| 523 | + self.assertEqual(int.from_bytes(range(5), 'little'), 17230332160) |
| 524 | + self.assertEqual(int.from_bytes(range(200,225), 'big'), 1260368276743602661175172759269383066378083427695751132536800) |
| 525 | + r = range(10) |
| 526 | + self.assertEqual(int.from_bytes(r[:], 'big'), 18591708106338011145) |
| 527 | + self.assertEqual(int.from_bytes(r[1:3], 'big'), 258) |
| 528 | + self.assertEqual(int.from_bytes(r[3:1], 'big'), 0) |
| 529 | + self.assertEqual(int.from_bytes(r[3:-1], 'big'), 3315799033608) |
| 530 | + |
| 531 | + def test_map(self): |
| 532 | + def myconvert(text): |
| 533 | + return int(text) |
| 534 | + self.assertEqual(int.from_bytes(map(myconvert, ["100","10","1"]), 'big'), 6556161) |
| 535 | + |
| 536 | + def test_from_byteslike_object(self): |
| 537 | + class mybyteslike(): |
| 538 | + def __bytes__(self): |
| 539 | + return bytes([10,20]) |
| 540 | + |
| 541 | + self.assertEqual(int.from_bytes(mybyteslike(), 'big'), 2580) |
| 542 | + |
| 543 | + def test_from_wrong_byteslike_object(self): |
| 544 | + class mybyteslike1(): |
| 545 | + def __bytes__(self): |
| 546 | + return range(3) |
| 547 | + |
| 548 | + self.assertRaises(TypeError, int.from_bytes, mybyteslike1(), 'big') |
| 549 | + |
| 550 | + class mybyteslike2(): |
| 551 | + def __bytes__(self): |
| 552 | + return array.array('b', [2, 2, 3]) |
| 553 | + |
| 554 | + self.assertRaises(TypeError, int.from_bytes, mybyteslike2(), 'big') |
| 555 | + |
| 556 | + def test_from_list_with_byteslike(self): |
| 557 | + class StrangeList(list): |
| 558 | + def __bytes__(self): |
| 559 | + return bytes([3]) |
| 560 | + def __iter__(self): |
| 561 | + return iter([10]) |
| 562 | + |
| 563 | + self.assertEqual(int.from_bytes(StrangeList([4,5]), 'big'), 3) |
0 commit comments