|
5 | 5 | import math |
6 | 6 | import operator |
7 | 7 | import unittest |
8 | | -import platform |
9 | 8 | import struct |
10 | 9 | import sys |
11 | 10 | import weakref |
@@ -435,56 +434,63 @@ def test_unpack_from(self): |
435 | 434 | self.assertEqual(s.unpack_from(buffer=test_string, offset=2), |
436 | 435 | (b'cd01',)) |
437 | 436 |
|
438 | | - def test_pack_into(self): |
| 437 | + def _test_pack_into(self, pack_into): |
439 | 438 | test_string = b'Reykjavik rocks, eow!' |
440 | | - writable_buf = array.array('b', b' '*100) |
441 | | - fmt = '21s' |
442 | | - s = struct.Struct(fmt) |
| 439 | + writable_buf = memoryview(array.array('b', b' '*100)) |
443 | 440 |
|
444 | 441 | # Test without offset |
445 | | - s.pack_into(writable_buf, 0, test_string) |
| 442 | + pack_into(writable_buf, 0, test_string) |
446 | 443 | from_buf = writable_buf.tobytes()[:len(test_string)] |
447 | 444 | self.assertEqual(from_buf, test_string) |
448 | 445 |
|
449 | 446 | # Test with offset. |
450 | | - s.pack_into(writable_buf, 10, test_string) |
| 447 | + pack_into(writable_buf, 10, test_string) |
451 | 448 | from_buf = writable_buf.tobytes()[:len(test_string)+10] |
452 | 449 | self.assertEqual(from_buf, test_string[:10] + test_string) |
453 | 450 |
|
| 451 | + # Test with negative offset. |
| 452 | + pack_into(writable_buf, -30, test_string) |
| 453 | + from_buf = writable_buf.tobytes()[-30:-30+len(test_string)] |
| 454 | + self.assertEqual(from_buf, test_string) |
| 455 | + |
454 | 456 | # Go beyond boundaries. |
455 | 457 | small_buf = array.array('b', b' '*10) |
456 | | - self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 0, |
457 | | - test_string) |
458 | | - self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 2, |
459 | | - test_string) |
| 458 | + with self.assertRaises((ValueError, struct.error)): |
| 459 | + pack_into(small_buf, 0, test_string) |
| 460 | + with self.assertRaises((ValueError, struct.error)): |
| 461 | + pack_into(writable_buf, 90, test_string) |
| 462 | + with self.assertRaises((ValueError, struct.error)): |
| 463 | + pack_into(writable_buf, -10, test_string) |
| 464 | + with self.assertRaises((ValueError, struct.error)): |
| 465 | + pack_into(writable_buf, 150, test_string) |
| 466 | + with self.assertRaises((ValueError, struct.error)): |
| 467 | + pack_into(writable_buf, -150, test_string) |
| 468 | + |
| 469 | + # Test invalid buffer. |
| 470 | + self.assertRaises(TypeError, pack_into, b' '*100, 0, test_string) |
| 471 | + self.assertRaises(TypeError, pack_into, ' '*100, 0, test_string) |
| 472 | + self.assertRaises(TypeError, pack_into, [0]*100, 0, test_string) |
| 473 | + self.assertRaises(TypeError, pack_into, None, 0, test_string) |
| 474 | + self.assertRaises(TypeError, pack_into, writable_buf[::2], 0, test_string) |
| 475 | + self.assertRaises(TypeError, pack_into, writable_buf[::-1], 0, test_string) |
| 476 | + |
| 477 | + # Test bogus offset (issue bpo-3694) |
| 478 | + with self.assertRaises(TypeError): |
| 479 | + pack_into(writable_buf, None, test_string) |
| 480 | + with self.assertRaises(TypeError): |
| 481 | + pack_into(writable_buf, 0.0, test_string) |
| 482 | + with self.assertRaises((IndexError, OverflowError)): |
| 483 | + pack_into(writable_buf, 2**1000, test_string) |
| 484 | + with self.assertRaises((IndexError, OverflowError)): |
| 485 | + pack_into(writable_buf, -2**1000, test_string) |
460 | 486 |
|
461 | | - # Test bogus offset (issue 3694) |
462 | | - sb = small_buf |
463 | | - self.assertRaises((TypeError, struct.error), struct.pack_into, b'', sb, |
464 | | - None) |
| 487 | + def test_pack_into(self): |
| 488 | + s = struct.Struct('21s') |
| 489 | + self._test_pack_into(s.pack_into) |
465 | 490 |
|
466 | 491 | def test_pack_into_fn(self): |
467 | | - test_string = b'Reykjavik rocks, eow!' |
468 | | - writable_buf = array.array('b', b' '*100) |
469 | | - fmt = '21s' |
470 | | - pack_into = lambda *args: struct.pack_into(fmt, *args) |
471 | | - |
472 | | - # Test without offset. |
473 | | - pack_into(writable_buf, 0, test_string) |
474 | | - from_buf = writable_buf.tobytes()[:len(test_string)] |
475 | | - self.assertEqual(from_buf, test_string) |
476 | | - |
477 | | - # Test with offset. |
478 | | - pack_into(writable_buf, 10, test_string) |
479 | | - from_buf = writable_buf.tobytes()[:len(test_string)+10] |
480 | | - self.assertEqual(from_buf, test_string[:10] + test_string) |
481 | | - |
482 | | - # Go beyond boundaries. |
483 | | - small_buf = array.array('b', b' '*10) |
484 | | - self.assertRaises((ValueError, struct.error), pack_into, small_buf, 0, |
485 | | - test_string) |
486 | | - self.assertRaises((ValueError, struct.error), pack_into, small_buf, 2, |
487 | | - test_string) |
| 492 | + pack_into = lambda *args: struct.pack_into('21s', *args) |
| 493 | + self._test_pack_into(pack_into) |
488 | 494 |
|
489 | 495 | def test_unpack_with_buffer(self): |
490 | 496 | # SF bug 1563759: struct.unpack doesn't support buffer protocol objects |
@@ -821,6 +827,18 @@ def test_endian_table_init_subinterpreters(self): |
821 | 827 | results = executor.map(exec, [code] * 5) |
822 | 828 | self.assertListEqual(list(results), [None] * 5) |
823 | 829 |
|
| 830 | + def test_operations_on_half_initialized_Struct(self): |
| 831 | + S = struct.Struct.__new__(struct.Struct) |
| 832 | + |
| 833 | + spam = array.array('b', b' ') |
| 834 | + self.assertRaises(RuntimeError, S.iter_unpack, spam) |
| 835 | + self.assertRaises(RuntimeError, S.pack, 1) |
| 836 | + self.assertRaises(RuntimeError, S.pack_into, spam, 1) |
| 837 | + self.assertRaises(RuntimeError, S.unpack, spam) |
| 838 | + self.assertRaises(RuntimeError, S.unpack_from, spam) |
| 839 | + self.assertRaises(RuntimeError, getattr, S, 'format') |
| 840 | + self.assertEqual(S.size, -1) |
| 841 | + |
824 | 842 |
|
825 | 843 | class UnpackIteratorTest(unittest.TestCase): |
826 | 844 | """ |
@@ -895,6 +913,7 @@ def test_module_func(self): |
895 | 913 | self.assertRaises(StopIteration, next, it) |
896 | 914 |
|
897 | 915 | def test_half_float(self): |
| 916 | + _testcapi = import_helper.import_module('_testcapi') |
898 | 917 | # Little-endian examples from: |
899 | 918 | # http://en.wikipedia.org/wiki/Half_precision_floating-point_format |
900 | 919 | format_bits_float__cleanRoundtrip_list = [ |
@@ -939,8 +958,8 @@ def test_half_float(self): |
939 | 958 |
|
940 | 959 | # Check that packing produces a bit pattern representing a quiet NaN: |
941 | 960 | # all exponent bits and the msb of the fraction should all be 1. |
942 | | - if platform.machine().startswith('parisc'): |
943 | | - # HP PA RISC uses 0 for quiet, see: |
| 961 | + if _testcapi.nan_msb_is_signaling: |
| 962 | + # HP PA RISC and some MIPS CPUs use 0 for quiet, see: |
944 | 963 | # https://en.wikipedia.org/wiki/NaN#Encoding |
945 | 964 | expected = 0x7c |
946 | 965 | else: |
|
0 commit comments