17db96d56Sopenharmony_cifrom collections import abc
27db96d56Sopenharmony_ciimport array
37db96d56Sopenharmony_ciimport gc
47db96d56Sopenharmony_ciimport math
57db96d56Sopenharmony_ciimport operator
67db96d56Sopenharmony_ciimport unittest
77db96d56Sopenharmony_ciimport struct
87db96d56Sopenharmony_ciimport sys
97db96d56Sopenharmony_ciimport weakref
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_cifrom test import support
127db96d56Sopenharmony_cifrom test.support import import_helper
137db96d56Sopenharmony_cifrom test.support.script_helper import assert_python_ok
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ciISBIGENDIAN = sys.byteorder == "big"
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ciinteger_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'n', 'N'
187db96d56Sopenharmony_cibyteorders = '', '@', '=', '<', '>', '!'
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_cidef iter_integer_formats(byteorders=byteorders):
217db96d56Sopenharmony_ci    for code in integer_codes:
227db96d56Sopenharmony_ci        for byteorder in byteorders:
237db96d56Sopenharmony_ci            if (byteorder not in ('', '@') and code in ('n', 'N')):
247db96d56Sopenharmony_ci                continue
257db96d56Sopenharmony_ci            yield code, byteorder
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_cidef string_reverse(s):
287db96d56Sopenharmony_ci    return s[::-1]
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_cidef bigendian_to_native(value):
317db96d56Sopenharmony_ci    if ISBIGENDIAN:
327db96d56Sopenharmony_ci        return value
337db96d56Sopenharmony_ci    else:
347db96d56Sopenharmony_ci        return string_reverse(value)
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ciclass StructTest(unittest.TestCase):
377db96d56Sopenharmony_ci    def test_isbigendian(self):
387db96d56Sopenharmony_ci        self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN)
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci    def test_consistence(self):
417db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.calcsize, 'Z')
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci        sz = struct.calcsize('i')
447db96d56Sopenharmony_ci        self.assertEqual(sz * 3, struct.calcsize('iii'))
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_ci        fmt = 'cbxxxxxxhhhhiillffd?'
477db96d56Sopenharmony_ci        fmt3 = '3c3b18x12h6i6l6f3d3?'
487db96d56Sopenharmony_ci        sz = struct.calcsize(fmt)
497db96d56Sopenharmony_ci        sz3 = struct.calcsize(fmt3)
507db96d56Sopenharmony_ci        self.assertEqual(sz * 3, sz3)
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, 'iii', 3)
537db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, 'i', 3, 3, 3)
547db96d56Sopenharmony_ci        self.assertRaises((TypeError, struct.error), struct.pack, 'i', 'foo')
557db96d56Sopenharmony_ci        self.assertRaises((TypeError, struct.error), struct.pack, 'P', 'foo')
567db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack, 'd', b'flap')
577db96d56Sopenharmony_ci        s = struct.pack('ii', 1, 2)
587db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack, 'iii', s)
597db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack, 'i', s)
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci    def test_transitiveness(self):
627db96d56Sopenharmony_ci        c = b'a'
637db96d56Sopenharmony_ci        b = 1
647db96d56Sopenharmony_ci        h = 255
657db96d56Sopenharmony_ci        i = 65535
667db96d56Sopenharmony_ci        l = 65536
677db96d56Sopenharmony_ci        f = 3.1415
687db96d56Sopenharmony_ci        d = 3.1415
697db96d56Sopenharmony_ci        t = True
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci        for prefix in ('', '@', '<', '>', '=', '!'):
727db96d56Sopenharmony_ci            for format in ('xcbhilfd?', 'xcBHILfd?'):
737db96d56Sopenharmony_ci                format = prefix + format
747db96d56Sopenharmony_ci                s = struct.pack(format, c, b, h, i, l, f, d, t)
757db96d56Sopenharmony_ci                cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s)
767db96d56Sopenharmony_ci                self.assertEqual(cp, c)
777db96d56Sopenharmony_ci                self.assertEqual(bp, b)
787db96d56Sopenharmony_ci                self.assertEqual(hp, h)
797db96d56Sopenharmony_ci                self.assertEqual(ip, i)
807db96d56Sopenharmony_ci                self.assertEqual(lp, l)
817db96d56Sopenharmony_ci                self.assertEqual(int(100 * fp), int(100 * f))
827db96d56Sopenharmony_ci                self.assertEqual(int(100 * dp), int(100 * d))
837db96d56Sopenharmony_ci                self.assertEqual(tp, t)
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci    def test_new_features(self):
867db96d56Sopenharmony_ci        # Test some of the new features in detail
877db96d56Sopenharmony_ci        # (format, argument, big-endian result, little-endian result, asymmetric)
887db96d56Sopenharmony_ci        tests = [
897db96d56Sopenharmony_ci            ('c', b'a', b'a', b'a', 0),
907db96d56Sopenharmony_ci            ('xc', b'a', b'\0a', b'\0a', 0),
917db96d56Sopenharmony_ci            ('cx', b'a', b'a\0', b'a\0', 0),
927db96d56Sopenharmony_ci            ('s', b'a', b'a', b'a', 0),
937db96d56Sopenharmony_ci            ('0s', b'helloworld', b'', b'', 1),
947db96d56Sopenharmony_ci            ('1s', b'helloworld', b'h', b'h', 1),
957db96d56Sopenharmony_ci            ('9s', b'helloworld', b'helloworl', b'helloworl', 1),
967db96d56Sopenharmony_ci            ('10s', b'helloworld', b'helloworld', b'helloworld', 0),
977db96d56Sopenharmony_ci            ('11s', b'helloworld', b'helloworld\0', b'helloworld\0', 1),
987db96d56Sopenharmony_ci            ('20s', b'helloworld', b'helloworld'+10*b'\0', b'helloworld'+10*b'\0', 1),
997db96d56Sopenharmony_ci            ('b', 7, b'\7', b'\7', 0),
1007db96d56Sopenharmony_ci            ('b', -7, b'\371', b'\371', 0),
1017db96d56Sopenharmony_ci            ('B', 7, b'\7', b'\7', 0),
1027db96d56Sopenharmony_ci            ('B', 249, b'\371', b'\371', 0),
1037db96d56Sopenharmony_ci            ('h', 700, b'\002\274', b'\274\002', 0),
1047db96d56Sopenharmony_ci            ('h', -700, b'\375D', b'D\375', 0),
1057db96d56Sopenharmony_ci            ('H', 700, b'\002\274', b'\274\002', 0),
1067db96d56Sopenharmony_ci            ('H', 0x10000-700, b'\375D', b'D\375', 0),
1077db96d56Sopenharmony_ci            ('i', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
1087db96d56Sopenharmony_ci            ('i', -70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
1097db96d56Sopenharmony_ci            ('I', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
1107db96d56Sopenharmony_ci            ('I', 0x100000000-70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
1117db96d56Sopenharmony_ci            ('l', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
1127db96d56Sopenharmony_ci            ('l', -70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
1137db96d56Sopenharmony_ci            ('L', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
1147db96d56Sopenharmony_ci            ('L', 0x100000000-70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
1157db96d56Sopenharmony_ci            ('f', 2.0, b'@\000\000\000', b'\000\000\000@', 0),
1167db96d56Sopenharmony_ci            ('d', 2.0, b'@\000\000\000\000\000\000\000',
1177db96d56Sopenharmony_ci                       b'\000\000\000\000\000\000\000@', 0),
1187db96d56Sopenharmony_ci            ('f', -2.0, b'\300\000\000\000', b'\000\000\000\300', 0),
1197db96d56Sopenharmony_ci            ('d', -2.0, b'\300\000\000\000\000\000\000\000',
1207db96d56Sopenharmony_ci                        b'\000\000\000\000\000\000\000\300', 0),
1217db96d56Sopenharmony_ci            ('?', 0, b'\0', b'\0', 0),
1227db96d56Sopenharmony_ci            ('?', 3, b'\1', b'\1', 1),
1237db96d56Sopenharmony_ci            ('?', True, b'\1', b'\1', 0),
1247db96d56Sopenharmony_ci            ('?', [], b'\0', b'\0', 1),
1257db96d56Sopenharmony_ci            ('?', (1,), b'\1', b'\1', 1),
1267db96d56Sopenharmony_ci        ]
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci        for fmt, arg, big, lil, asy in tests:
1297db96d56Sopenharmony_ci            for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
1307db96d56Sopenharmony_ci                                ('='+fmt, ISBIGENDIAN and big or lil)]:
1317db96d56Sopenharmony_ci                res = struct.pack(xfmt, arg)
1327db96d56Sopenharmony_ci                self.assertEqual(res, exp)
1337db96d56Sopenharmony_ci                self.assertEqual(struct.calcsize(xfmt), len(res))
1347db96d56Sopenharmony_ci                rev = struct.unpack(xfmt, res)[0]
1357db96d56Sopenharmony_ci                if rev != arg:
1367db96d56Sopenharmony_ci                    self.assertTrue(asy)
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    def test_calcsize(self):
1397db96d56Sopenharmony_ci        expected_size = {
1407db96d56Sopenharmony_ci            'b': 1, 'B': 1,
1417db96d56Sopenharmony_ci            'h': 2, 'H': 2,
1427db96d56Sopenharmony_ci            'i': 4, 'I': 4,
1437db96d56Sopenharmony_ci            'l': 4, 'L': 4,
1447db96d56Sopenharmony_ci            'q': 8, 'Q': 8,
1457db96d56Sopenharmony_ci            }
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci        # standard integer sizes
1487db96d56Sopenharmony_ci        for code, byteorder in iter_integer_formats(('=', '<', '>', '!')):
1497db96d56Sopenharmony_ci            format = byteorder+code
1507db96d56Sopenharmony_ci            size = struct.calcsize(format)
1517db96d56Sopenharmony_ci            self.assertEqual(size, expected_size[code])
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci        # native integer sizes
1547db96d56Sopenharmony_ci        native_pairs = 'bB', 'hH', 'iI', 'lL', 'nN', 'qQ'
1557db96d56Sopenharmony_ci        for format_pair in native_pairs:
1567db96d56Sopenharmony_ci            for byteorder in '', '@':
1577db96d56Sopenharmony_ci                signed_size = struct.calcsize(byteorder + format_pair[0])
1587db96d56Sopenharmony_ci                unsigned_size = struct.calcsize(byteorder + format_pair[1])
1597db96d56Sopenharmony_ci                self.assertEqual(signed_size, unsigned_size)
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci        # bounds for native integer sizes
1627db96d56Sopenharmony_ci        self.assertEqual(struct.calcsize('b'), 1)
1637db96d56Sopenharmony_ci        self.assertLessEqual(2, struct.calcsize('h'))
1647db96d56Sopenharmony_ci        self.assertLessEqual(4, struct.calcsize('l'))
1657db96d56Sopenharmony_ci        self.assertLessEqual(struct.calcsize('h'), struct.calcsize('i'))
1667db96d56Sopenharmony_ci        self.assertLessEqual(struct.calcsize('i'), struct.calcsize('l'))
1677db96d56Sopenharmony_ci        self.assertLessEqual(8, struct.calcsize('q'))
1687db96d56Sopenharmony_ci        self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))
1697db96d56Sopenharmony_ci        self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('i'))
1707db96d56Sopenharmony_ci        self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('P'))
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ci    def test_integers(self):
1737db96d56Sopenharmony_ci        # Integer tests (bBhHiIlLqQnN).
1747db96d56Sopenharmony_ci        import binascii
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_ci        class IntTester(unittest.TestCase):
1777db96d56Sopenharmony_ci            def __init__(self, format):
1787db96d56Sopenharmony_ci                super(IntTester, self).__init__(methodName='test_one')
1797db96d56Sopenharmony_ci                self.format = format
1807db96d56Sopenharmony_ci                self.code = format[-1]
1817db96d56Sopenharmony_ci                self.byteorder = format[:-1]
1827db96d56Sopenharmony_ci                if not self.byteorder in byteorders:
1837db96d56Sopenharmony_ci                    raise ValueError("unrecognized packing byteorder: %s" %
1847db96d56Sopenharmony_ci                                     self.byteorder)
1857db96d56Sopenharmony_ci                self.bytesize = struct.calcsize(format)
1867db96d56Sopenharmony_ci                self.bitsize = self.bytesize * 8
1877db96d56Sopenharmony_ci                if self.code in tuple('bhilqn'):
1887db96d56Sopenharmony_ci                    self.signed = True
1897db96d56Sopenharmony_ci                    self.min_value = -(2**(self.bitsize-1))
1907db96d56Sopenharmony_ci                    self.max_value = 2**(self.bitsize-1) - 1
1917db96d56Sopenharmony_ci                elif self.code in tuple('BHILQN'):
1927db96d56Sopenharmony_ci                    self.signed = False
1937db96d56Sopenharmony_ci                    self.min_value = 0
1947db96d56Sopenharmony_ci                    self.max_value = 2**self.bitsize - 1
1957db96d56Sopenharmony_ci                else:
1967db96d56Sopenharmony_ci                    raise ValueError("unrecognized format code: %s" %
1977db96d56Sopenharmony_ci                                     self.code)
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci            def test_one(self, x, pack=struct.pack,
2007db96d56Sopenharmony_ci                                  unpack=struct.unpack,
2017db96d56Sopenharmony_ci                                  unhexlify=binascii.unhexlify):
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci                format = self.format
2047db96d56Sopenharmony_ci                if self.min_value <= x <= self.max_value:
2057db96d56Sopenharmony_ci                    expected = x
2067db96d56Sopenharmony_ci                    if self.signed and x < 0:
2077db96d56Sopenharmony_ci                        expected += 1 << self.bitsize
2087db96d56Sopenharmony_ci                    self.assertGreaterEqual(expected, 0)
2097db96d56Sopenharmony_ci                    expected = '%x' % expected
2107db96d56Sopenharmony_ci                    if len(expected) & 1:
2117db96d56Sopenharmony_ci                        expected = "0" + expected
2127db96d56Sopenharmony_ci                    expected = expected.encode('ascii')
2137db96d56Sopenharmony_ci                    expected = unhexlify(expected)
2147db96d56Sopenharmony_ci                    expected = (b"\x00" * (self.bytesize - len(expected)) +
2157db96d56Sopenharmony_ci                                expected)
2167db96d56Sopenharmony_ci                    if (self.byteorder == '<' or
2177db96d56Sopenharmony_ci                        self.byteorder in ('', '@', '=') and not ISBIGENDIAN):
2187db96d56Sopenharmony_ci                        expected = string_reverse(expected)
2197db96d56Sopenharmony_ci                    self.assertEqual(len(expected), self.bytesize)
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci                    # Pack work?
2227db96d56Sopenharmony_ci                    got = pack(format, x)
2237db96d56Sopenharmony_ci                    self.assertEqual(got, expected)
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci                    # Unpack work?
2267db96d56Sopenharmony_ci                    retrieved = unpack(format, got)[0]
2277db96d56Sopenharmony_ci                    self.assertEqual(x, retrieved)
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci                    # Adding any byte should cause a "too big" error.
2307db96d56Sopenharmony_ci                    self.assertRaises((struct.error, TypeError), unpack, format,
2317db96d56Sopenharmony_ci                                                                 b'\x01' + got)
2327db96d56Sopenharmony_ci                else:
2337db96d56Sopenharmony_ci                    # x is out of range -- verify pack realizes that.
2347db96d56Sopenharmony_ci                    self.assertRaises((OverflowError, ValueError, struct.error),
2357db96d56Sopenharmony_ci                                      pack, format, x)
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci            def run(self):
2387db96d56Sopenharmony_ci                from random import randrange
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci                # Create all interesting powers of 2.
2417db96d56Sopenharmony_ci                values = []
2427db96d56Sopenharmony_ci                for exp in range(self.bitsize + 3):
2437db96d56Sopenharmony_ci                    values.append(1 << exp)
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci                # Add some random values.
2467db96d56Sopenharmony_ci                for i in range(self.bitsize):
2477db96d56Sopenharmony_ci                    val = 0
2487db96d56Sopenharmony_ci                    for j in range(self.bytesize):
2497db96d56Sopenharmony_ci                        val = (val << 8) | randrange(256)
2507db96d56Sopenharmony_ci                    values.append(val)
2517db96d56Sopenharmony_ci
2527db96d56Sopenharmony_ci                # Values absorbed from other tests
2537db96d56Sopenharmony_ci                values.extend([300, 700000, sys.maxsize*4])
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ci                # Try all those, and their negations, and +-1 from
2567db96d56Sopenharmony_ci                # them.  Note that this tests all power-of-2
2577db96d56Sopenharmony_ci                # boundaries in range, and a few out of range, plus
2587db96d56Sopenharmony_ci                # +-(2**n +- 1).
2597db96d56Sopenharmony_ci                for base in values:
2607db96d56Sopenharmony_ci                    for val in -base, base:
2617db96d56Sopenharmony_ci                        for incr in -1, 0, 1:
2627db96d56Sopenharmony_ci                            x = val + incr
2637db96d56Sopenharmony_ci                            self.test_one(x)
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_ci                # Some error cases.
2667db96d56Sopenharmony_ci                class NotAnInt:
2677db96d56Sopenharmony_ci                    def __int__(self):
2687db96d56Sopenharmony_ci                        return 42
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci                # Objects with an '__index__' method should be allowed
2717db96d56Sopenharmony_ci                # to pack as integers.  That is assuming the implemented
2727db96d56Sopenharmony_ci                # '__index__' method returns an 'int'.
2737db96d56Sopenharmony_ci                class Indexable(object):
2747db96d56Sopenharmony_ci                    def __init__(self, value):
2757db96d56Sopenharmony_ci                        self._value = value
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci                    def __index__(self):
2787db96d56Sopenharmony_ci                        return self._value
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci                # If the '__index__' method raises a type error, then
2817db96d56Sopenharmony_ci                # '__int__' should be used with a deprecation warning.
2827db96d56Sopenharmony_ci                class BadIndex(object):
2837db96d56Sopenharmony_ci                    def __index__(self):
2847db96d56Sopenharmony_ci                        raise TypeError
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci                    def __int__(self):
2877db96d56Sopenharmony_ci                        return 42
2887db96d56Sopenharmony_ci
2897db96d56Sopenharmony_ci                self.assertRaises((TypeError, struct.error),
2907db96d56Sopenharmony_ci                                  struct.pack, self.format,
2917db96d56Sopenharmony_ci                                  "a string")
2927db96d56Sopenharmony_ci                self.assertRaises((TypeError, struct.error),
2937db96d56Sopenharmony_ci                                  struct.pack, self.format,
2947db96d56Sopenharmony_ci                                  randrange)
2957db96d56Sopenharmony_ci                self.assertRaises((TypeError, struct.error),
2967db96d56Sopenharmony_ci                                  struct.pack, self.format,
2977db96d56Sopenharmony_ci                                  3+42j)
2987db96d56Sopenharmony_ci                self.assertRaises((TypeError, struct.error),
2997db96d56Sopenharmony_ci                                  struct.pack, self.format,
3007db96d56Sopenharmony_ci                                  NotAnInt())
3017db96d56Sopenharmony_ci                self.assertRaises((TypeError, struct.error),
3027db96d56Sopenharmony_ci                                  struct.pack, self.format,
3037db96d56Sopenharmony_ci                                  BadIndex())
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_ci                # Check for legitimate values from '__index__'.
3067db96d56Sopenharmony_ci                for obj in (Indexable(0), Indexable(10), Indexable(17),
3077db96d56Sopenharmony_ci                            Indexable(42), Indexable(100), Indexable(127)):
3087db96d56Sopenharmony_ci                    try:
3097db96d56Sopenharmony_ci                        struct.pack(format, obj)
3107db96d56Sopenharmony_ci                    except:
3117db96d56Sopenharmony_ci                        self.fail("integer code pack failed on object "
3127db96d56Sopenharmony_ci                                  "with '__index__' method")
3137db96d56Sopenharmony_ci
3147db96d56Sopenharmony_ci                # Check for bogus values from '__index__'.
3157db96d56Sopenharmony_ci                for obj in (Indexable(b'a'), Indexable('b'), Indexable(None),
3167db96d56Sopenharmony_ci                            Indexable({'a': 1}), Indexable([1, 2, 3])):
3177db96d56Sopenharmony_ci                    self.assertRaises((TypeError, struct.error),
3187db96d56Sopenharmony_ci                                      struct.pack, self.format,
3197db96d56Sopenharmony_ci                                      obj)
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_ci        for code, byteorder in iter_integer_formats():
3227db96d56Sopenharmony_ci            format = byteorder+code
3237db96d56Sopenharmony_ci            t = IntTester(format)
3247db96d56Sopenharmony_ci            t.run()
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci    def test_nN_code(self):
3277db96d56Sopenharmony_ci        # n and N don't exist in standard sizes
3287db96d56Sopenharmony_ci        def assertStructError(func, *args, **kwargs):
3297db96d56Sopenharmony_ci            with self.assertRaises(struct.error) as cm:
3307db96d56Sopenharmony_ci                func(*args, **kwargs)
3317db96d56Sopenharmony_ci            self.assertIn("bad char in struct format", str(cm.exception))
3327db96d56Sopenharmony_ci        for code in 'nN':
3337db96d56Sopenharmony_ci            for byteorder in ('=', '<', '>', '!'):
3347db96d56Sopenharmony_ci                format = byteorder+code
3357db96d56Sopenharmony_ci                assertStructError(struct.calcsize, format)
3367db96d56Sopenharmony_ci                assertStructError(struct.pack, format, 0)
3377db96d56Sopenharmony_ci                assertStructError(struct.unpack, format, b"")
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci    def test_p_code(self):
3407db96d56Sopenharmony_ci        # Test p ("Pascal string") code.
3417db96d56Sopenharmony_ci        for code, input, expected, expectedback in [
3427db96d56Sopenharmony_ci                ('p',  b'abc', b'\x00',            b''),
3437db96d56Sopenharmony_ci                ('1p', b'abc', b'\x00',            b''),
3447db96d56Sopenharmony_ci                ('2p', b'abc', b'\x01a',           b'a'),
3457db96d56Sopenharmony_ci                ('3p', b'abc', b'\x02ab',          b'ab'),
3467db96d56Sopenharmony_ci                ('4p', b'abc', b'\x03abc',         b'abc'),
3477db96d56Sopenharmony_ci                ('5p', b'abc', b'\x03abc\x00',     b'abc'),
3487db96d56Sopenharmony_ci                ('6p', b'abc', b'\x03abc\x00\x00', b'abc'),
3497db96d56Sopenharmony_ci                ('1000p', b'x'*1000, b'\xff' + b'x'*999, b'x'*255)]:
3507db96d56Sopenharmony_ci            got = struct.pack(code, input)
3517db96d56Sopenharmony_ci            self.assertEqual(got, expected)
3527db96d56Sopenharmony_ci            (got,) = struct.unpack(code, got)
3537db96d56Sopenharmony_ci            self.assertEqual(got, expectedback)
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci    def test_705836(self):
3567db96d56Sopenharmony_ci        # SF bug 705836.  "<f" and ">f" had a severe rounding bug, where a carry
3577db96d56Sopenharmony_ci        # from the low-order discarded bits could propagate into the exponent
3587db96d56Sopenharmony_ci        # field, causing the result to be wrong by a factor of 2.
3597db96d56Sopenharmony_ci        for base in range(1, 33):
3607db96d56Sopenharmony_ci            # smaller <- largest representable float less than base.
3617db96d56Sopenharmony_ci            delta = 0.5
3627db96d56Sopenharmony_ci            while base - delta / 2.0 != base:
3637db96d56Sopenharmony_ci                delta /= 2.0
3647db96d56Sopenharmony_ci            smaller = base - delta
3657db96d56Sopenharmony_ci            # Packing this rounds away a solid string of trailing 1 bits.
3667db96d56Sopenharmony_ci            packed = struct.pack("<f", smaller)
3677db96d56Sopenharmony_ci            unpacked = struct.unpack("<f", packed)[0]
3687db96d56Sopenharmony_ci            # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
3697db96d56Sopenharmony_ci            # 16, respectively.
3707db96d56Sopenharmony_ci            self.assertEqual(base, unpacked)
3717db96d56Sopenharmony_ci            bigpacked = struct.pack(">f", smaller)
3727db96d56Sopenharmony_ci            self.assertEqual(bigpacked, string_reverse(packed))
3737db96d56Sopenharmony_ci            unpacked = struct.unpack(">f", bigpacked)[0]
3747db96d56Sopenharmony_ci            self.assertEqual(base, unpacked)
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ci        # Largest finite IEEE single.
3777db96d56Sopenharmony_ci        big = (1 << 24) - 1
3787db96d56Sopenharmony_ci        big = math.ldexp(big, 127 - 23)
3797db96d56Sopenharmony_ci        packed = struct.pack(">f", big)
3807db96d56Sopenharmony_ci        unpacked = struct.unpack(">f", packed)[0]
3817db96d56Sopenharmony_ci        self.assertEqual(big, unpacked)
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci        # The same, but tack on a 1 bit so it rounds up to infinity.
3847db96d56Sopenharmony_ci        big = (1 << 25) - 1
3857db96d56Sopenharmony_ci        big = math.ldexp(big, 127 - 24)
3867db96d56Sopenharmony_ci        self.assertRaises(OverflowError, struct.pack, ">f", big)
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci    def test_1530559(self):
3897db96d56Sopenharmony_ci        for code, byteorder in iter_integer_formats():
3907db96d56Sopenharmony_ci            format = byteorder + code
3917db96d56Sopenharmony_ci            self.assertRaises(struct.error, struct.pack, format, 1.0)
3927db96d56Sopenharmony_ci            self.assertRaises(struct.error, struct.pack, format, 1.5)
3937db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, 'P', 1.0)
3947db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, 'P', 1.5)
3957db96d56Sopenharmony_ci
3967db96d56Sopenharmony_ci    def test_unpack_from(self):
3977db96d56Sopenharmony_ci        test_string = b'abcd01234'
3987db96d56Sopenharmony_ci        fmt = '4s'
3997db96d56Sopenharmony_ci        s = struct.Struct(fmt)
4007db96d56Sopenharmony_ci        for cls in (bytes, bytearray):
4017db96d56Sopenharmony_ci            data = cls(test_string)
4027db96d56Sopenharmony_ci            self.assertEqual(s.unpack_from(data), (b'abcd',))
4037db96d56Sopenharmony_ci            self.assertEqual(s.unpack_from(data, 2), (b'cd01',))
4047db96d56Sopenharmony_ci            self.assertEqual(s.unpack_from(data, 4), (b'0123',))
4057db96d56Sopenharmony_ci            for i in range(6):
4067db96d56Sopenharmony_ci                self.assertEqual(s.unpack_from(data, i), (data[i:i+4],))
4077db96d56Sopenharmony_ci            for i in range(6, len(test_string) + 1):
4087db96d56Sopenharmony_ci                self.assertRaises(struct.error, s.unpack_from, data, i)
4097db96d56Sopenharmony_ci        for cls in (bytes, bytearray):
4107db96d56Sopenharmony_ci            data = cls(test_string)
4117db96d56Sopenharmony_ci            self.assertEqual(struct.unpack_from(fmt, data), (b'abcd',))
4127db96d56Sopenharmony_ci            self.assertEqual(struct.unpack_from(fmt, data, 2), (b'cd01',))
4137db96d56Sopenharmony_ci            self.assertEqual(struct.unpack_from(fmt, data, 4), (b'0123',))
4147db96d56Sopenharmony_ci            for i in range(6):
4157db96d56Sopenharmony_ci                self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],))
4167db96d56Sopenharmony_ci            for i in range(6, len(test_string) + 1):
4177db96d56Sopenharmony_ci                self.assertRaises(struct.error, struct.unpack_from, fmt, data, i)
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_ci        # keyword arguments
4207db96d56Sopenharmony_ci        self.assertEqual(s.unpack_from(buffer=test_string, offset=2),
4217db96d56Sopenharmony_ci                         (b'cd01',))
4227db96d56Sopenharmony_ci
4237db96d56Sopenharmony_ci    def test_pack_into(self):
4247db96d56Sopenharmony_ci        test_string = b'Reykjavik rocks, eow!'
4257db96d56Sopenharmony_ci        writable_buf = array.array('b', b' '*100)
4267db96d56Sopenharmony_ci        fmt = '21s'
4277db96d56Sopenharmony_ci        s = struct.Struct(fmt)
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci        # Test without offset
4307db96d56Sopenharmony_ci        s.pack_into(writable_buf, 0, test_string)
4317db96d56Sopenharmony_ci        from_buf = writable_buf.tobytes()[:len(test_string)]
4327db96d56Sopenharmony_ci        self.assertEqual(from_buf, test_string)
4337db96d56Sopenharmony_ci
4347db96d56Sopenharmony_ci        # Test with offset.
4357db96d56Sopenharmony_ci        s.pack_into(writable_buf, 10, test_string)
4367db96d56Sopenharmony_ci        from_buf = writable_buf.tobytes()[:len(test_string)+10]
4377db96d56Sopenharmony_ci        self.assertEqual(from_buf, test_string[:10] + test_string)
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_ci        # Go beyond boundaries.
4407db96d56Sopenharmony_ci        small_buf = array.array('b', b' '*10)
4417db96d56Sopenharmony_ci        self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 0,
4427db96d56Sopenharmony_ci                          test_string)
4437db96d56Sopenharmony_ci        self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 2,
4447db96d56Sopenharmony_ci                          test_string)
4457db96d56Sopenharmony_ci
4467db96d56Sopenharmony_ci        # Test bogus offset (issue 3694)
4477db96d56Sopenharmony_ci        sb = small_buf
4487db96d56Sopenharmony_ci        self.assertRaises((TypeError, struct.error), struct.pack_into, b'', sb,
4497db96d56Sopenharmony_ci                          None)
4507db96d56Sopenharmony_ci
4517db96d56Sopenharmony_ci    def test_pack_into_fn(self):
4527db96d56Sopenharmony_ci        test_string = b'Reykjavik rocks, eow!'
4537db96d56Sopenharmony_ci        writable_buf = array.array('b', b' '*100)
4547db96d56Sopenharmony_ci        fmt = '21s'
4557db96d56Sopenharmony_ci        pack_into = lambda *args: struct.pack_into(fmt, *args)
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci        # Test without offset.
4587db96d56Sopenharmony_ci        pack_into(writable_buf, 0, test_string)
4597db96d56Sopenharmony_ci        from_buf = writable_buf.tobytes()[:len(test_string)]
4607db96d56Sopenharmony_ci        self.assertEqual(from_buf, test_string)
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci        # Test with offset.
4637db96d56Sopenharmony_ci        pack_into(writable_buf, 10, test_string)
4647db96d56Sopenharmony_ci        from_buf = writable_buf.tobytes()[:len(test_string)+10]
4657db96d56Sopenharmony_ci        self.assertEqual(from_buf, test_string[:10] + test_string)
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci        # Go beyond boundaries.
4687db96d56Sopenharmony_ci        small_buf = array.array('b', b' '*10)
4697db96d56Sopenharmony_ci        self.assertRaises((ValueError, struct.error), pack_into, small_buf, 0,
4707db96d56Sopenharmony_ci                          test_string)
4717db96d56Sopenharmony_ci        self.assertRaises((ValueError, struct.error), pack_into, small_buf, 2,
4727db96d56Sopenharmony_ci                          test_string)
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci    def test_unpack_with_buffer(self):
4757db96d56Sopenharmony_ci        # SF bug 1563759: struct.unpack doesn't support buffer protocol objects
4767db96d56Sopenharmony_ci        data1 = array.array('B', b'\x12\x34\x56\x78')
4777db96d56Sopenharmony_ci        data2 = memoryview(b'\x12\x34\x56\x78') # XXX b'......XXXX......', 6, 4
4787db96d56Sopenharmony_ci        for data in [data1, data2]:
4797db96d56Sopenharmony_ci            value, = struct.unpack('>I', data)
4807db96d56Sopenharmony_ci            self.assertEqual(value, 0x12345678)
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci    def test_bool(self):
4837db96d56Sopenharmony_ci        class ExplodingBool(object):
4847db96d56Sopenharmony_ci            def __bool__(self):
4857db96d56Sopenharmony_ci                raise OSError
4867db96d56Sopenharmony_ci        for prefix in tuple("<>!=")+('',):
4877db96d56Sopenharmony_ci            false = (), [], [], '', 0
4887db96d56Sopenharmony_ci            true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2
4897db96d56Sopenharmony_ci
4907db96d56Sopenharmony_ci            falseFormat = prefix + '?' * len(false)
4917db96d56Sopenharmony_ci            packedFalse = struct.pack(falseFormat, *false)
4927db96d56Sopenharmony_ci            unpackedFalse = struct.unpack(falseFormat, packedFalse)
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_ci            trueFormat = prefix + '?' * len(true)
4957db96d56Sopenharmony_ci            packedTrue = struct.pack(trueFormat, *true)
4967db96d56Sopenharmony_ci            unpackedTrue = struct.unpack(trueFormat, packedTrue)
4977db96d56Sopenharmony_ci
4987db96d56Sopenharmony_ci            self.assertEqual(len(true), len(unpackedTrue))
4997db96d56Sopenharmony_ci            self.assertEqual(len(false), len(unpackedFalse))
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci            for t in unpackedFalse:
5027db96d56Sopenharmony_ci                self.assertFalse(t)
5037db96d56Sopenharmony_ci            for t in unpackedTrue:
5047db96d56Sopenharmony_ci                self.assertTrue(t)
5057db96d56Sopenharmony_ci
5067db96d56Sopenharmony_ci            packed = struct.pack(prefix+'?', 1)
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci            self.assertEqual(len(packed), struct.calcsize(prefix+'?'))
5097db96d56Sopenharmony_ci
5107db96d56Sopenharmony_ci            if len(packed) != 1:
5117db96d56Sopenharmony_ci                self.assertFalse(prefix, msg='encoded bool is not one byte: %r'
5127db96d56Sopenharmony_ci                                             %packed)
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ci            try:
5157db96d56Sopenharmony_ci                struct.pack(prefix + '?', ExplodingBool())
5167db96d56Sopenharmony_ci            except OSError:
5177db96d56Sopenharmony_ci                pass
5187db96d56Sopenharmony_ci            else:
5197db96d56Sopenharmony_ci                self.fail("Expected OSError: struct.pack(%r, "
5207db96d56Sopenharmony_ci                          "ExplodingBool())" % (prefix + '?'))
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci        for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
5237db96d56Sopenharmony_ci            self.assertTrue(struct.unpack('>?', c)[0])
5247db96d56Sopenharmony_ci
5257db96d56Sopenharmony_ci    def test_count_overflow(self):
5267db96d56Sopenharmony_ci        hugecount = '{}b'.format(sys.maxsize+1)
5277db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.calcsize, hugecount)
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_ci        hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2)
5307db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.calcsize, hugecount2)
5317db96d56Sopenharmony_ci
5327db96d56Sopenharmony_ci    def test_trailing_counter(self):
5337db96d56Sopenharmony_ci        store = array.array('b', b' '*100)
5347db96d56Sopenharmony_ci
5357db96d56Sopenharmony_ci        # format lists containing only count spec should result in an error
5367db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, '12345')
5377db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack, '12345', b'')
5387db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack_into, '12345', store, 0)
5397db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0)
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci        # Format lists with trailing count spec should result in an error
5427db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, 'c12345', 'x')
5437db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack, 'c12345', b'x')
5447db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0,
5457db96d56Sopenharmony_ci                           'x')
5467db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack_from, 'c12345', store,
5477db96d56Sopenharmony_ci                           0)
5487db96d56Sopenharmony_ci
5497db96d56Sopenharmony_ci        # Mixed format tests
5507db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs')
5517db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack, '14s42',
5527db96d56Sopenharmony_ci                          b'spam and eggs')
5537db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0,
5547db96d56Sopenharmony_ci                          'spam and eggs')
5557db96d56Sopenharmony_ci        self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0)
5567db96d56Sopenharmony_ci
5577db96d56Sopenharmony_ci    def test_Struct_reinitialization(self):
5587db96d56Sopenharmony_ci        # Issue 9422: there was a memory leak when reinitializing a
5597db96d56Sopenharmony_ci        # Struct instance.  This test can be used to detect the leak
5607db96d56Sopenharmony_ci        # when running with regrtest -L.
5617db96d56Sopenharmony_ci        s = struct.Struct('i')
5627db96d56Sopenharmony_ci        s.__init__('ii')
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_ci    def check_sizeof(self, format_str, number_of_codes):
5657db96d56Sopenharmony_ci        # The size of 'PyStructObject'
5667db96d56Sopenharmony_ci        totalsize = support.calcobjsize('2n3P')
5677db96d56Sopenharmony_ci        # The size taken up by the 'formatcode' dynamic array
5687db96d56Sopenharmony_ci        totalsize += struct.calcsize('P3n0P') * (number_of_codes + 1)
5697db96d56Sopenharmony_ci        support.check_sizeof(self, struct.Struct(format_str), totalsize)
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci    @support.cpython_only
5727db96d56Sopenharmony_ci    def test__sizeof__(self):
5737db96d56Sopenharmony_ci        for code in integer_codes:
5747db96d56Sopenharmony_ci            self.check_sizeof(code, 1)
5757db96d56Sopenharmony_ci        self.check_sizeof('BHILfdspP', 9)
5767db96d56Sopenharmony_ci        self.check_sizeof('B' * 1234, 1234)
5777db96d56Sopenharmony_ci        self.check_sizeof('fd', 2)
5787db96d56Sopenharmony_ci        self.check_sizeof('xxxxxxxxxxxxxx', 0)
5797db96d56Sopenharmony_ci        self.check_sizeof('100H', 1)
5807db96d56Sopenharmony_ci        self.check_sizeof('187s', 1)
5817db96d56Sopenharmony_ci        self.check_sizeof('20p', 1)
5827db96d56Sopenharmony_ci        self.check_sizeof('0s', 1)
5837db96d56Sopenharmony_ci        self.check_sizeof('0c', 0)
5847db96d56Sopenharmony_ci
5857db96d56Sopenharmony_ci    def test_boundary_error_message(self):
5867db96d56Sopenharmony_ci        regex1 = (
5877db96d56Sopenharmony_ci            r'pack_into requires a buffer of at least 6 '
5887db96d56Sopenharmony_ci            r'bytes for packing 1 bytes at offset 5 '
5897db96d56Sopenharmony_ci            r'\(actual buffer size is 1\)'
5907db96d56Sopenharmony_ci        )
5917db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, regex1):
5927db96d56Sopenharmony_ci            struct.pack_into('b', bytearray(1), 5, 1)
5937db96d56Sopenharmony_ci
5947db96d56Sopenharmony_ci        regex2 = (
5957db96d56Sopenharmony_ci            r'unpack_from requires a buffer of at least 6 '
5967db96d56Sopenharmony_ci            r'bytes for unpacking 1 bytes at offset 5 '
5977db96d56Sopenharmony_ci            r'\(actual buffer size is 1\)'
5987db96d56Sopenharmony_ci        )
5997db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, regex2):
6007db96d56Sopenharmony_ci            struct.unpack_from('b', bytearray(1), 5)
6017db96d56Sopenharmony_ci
6027db96d56Sopenharmony_ci    def test_boundary_error_message_with_negative_offset(self):
6037db96d56Sopenharmony_ci        byte_list = bytearray(10)
6047db96d56Sopenharmony_ci        with self.assertRaisesRegex(
6057db96d56Sopenharmony_ci                struct.error,
6067db96d56Sopenharmony_ci                r'no space to pack 4 bytes at offset -2'):
6077db96d56Sopenharmony_ci            struct.pack_into('<I', byte_list, -2, 123)
6087db96d56Sopenharmony_ci
6097db96d56Sopenharmony_ci        with self.assertRaisesRegex(
6107db96d56Sopenharmony_ci                struct.error,
6117db96d56Sopenharmony_ci                'offset -11 out of range for 10-byte buffer'):
6127db96d56Sopenharmony_ci            struct.pack_into('<B', byte_list, -11, 123)
6137db96d56Sopenharmony_ci
6147db96d56Sopenharmony_ci        with self.assertRaisesRegex(
6157db96d56Sopenharmony_ci                struct.error,
6167db96d56Sopenharmony_ci                r'not enough data to unpack 4 bytes at offset -2'):
6177db96d56Sopenharmony_ci            struct.unpack_from('<I', byte_list, -2)
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_ci        with self.assertRaisesRegex(
6207db96d56Sopenharmony_ci                struct.error,
6217db96d56Sopenharmony_ci                "offset -11 out of range for 10-byte buffer"):
6227db96d56Sopenharmony_ci            struct.unpack_from('<B', byte_list, -11)
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_ci    def test_boundary_error_message_with_large_offset(self):
6257db96d56Sopenharmony_ci        # Test overflows cause by large offset and value size (issue 30245)
6267db96d56Sopenharmony_ci        regex1 = (
6277db96d56Sopenharmony_ci            r'pack_into requires a buffer of at least ' + str(sys.maxsize + 4) +
6287db96d56Sopenharmony_ci            r' bytes for packing 4 bytes at offset ' + str(sys.maxsize) +
6297db96d56Sopenharmony_ci            r' \(actual buffer size is 10\)'
6307db96d56Sopenharmony_ci        )
6317db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, regex1):
6327db96d56Sopenharmony_ci            struct.pack_into('<I', bytearray(10), sys.maxsize, 1)
6337db96d56Sopenharmony_ci
6347db96d56Sopenharmony_ci        regex2 = (
6357db96d56Sopenharmony_ci            r'unpack_from requires a buffer of at least ' + str(sys.maxsize + 4) +
6367db96d56Sopenharmony_ci            r' bytes for unpacking 4 bytes at offset ' + str(sys.maxsize) +
6377db96d56Sopenharmony_ci            r' \(actual buffer size is 10\)'
6387db96d56Sopenharmony_ci        )
6397db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, regex2):
6407db96d56Sopenharmony_ci            struct.unpack_from('<I', bytearray(10), sys.maxsize)
6417db96d56Sopenharmony_ci
6427db96d56Sopenharmony_ci    def test_issue29802(self):
6437db96d56Sopenharmony_ci        # When the second argument of struct.unpack() was of wrong type
6447db96d56Sopenharmony_ci        # the Struct object was decrefed twice and the reference to
6457db96d56Sopenharmony_ci        # deallocated object was left in a cache.
6467db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
6477db96d56Sopenharmony_ci            struct.unpack('b', 0)
6487db96d56Sopenharmony_ci        # Shouldn't crash.
6497db96d56Sopenharmony_ci        self.assertEqual(struct.unpack('b', b'a'), (b'a'[0],))
6507db96d56Sopenharmony_ci
6517db96d56Sopenharmony_ci    def test_format_attr(self):
6527db96d56Sopenharmony_ci        s = struct.Struct('=i2H')
6537db96d56Sopenharmony_ci        self.assertEqual(s.format, '=i2H')
6547db96d56Sopenharmony_ci
6557db96d56Sopenharmony_ci        # use a bytes string
6567db96d56Sopenharmony_ci        s2 = struct.Struct(s.format.encode())
6577db96d56Sopenharmony_ci        self.assertEqual(s2.format, s.format)
6587db96d56Sopenharmony_ci
6597db96d56Sopenharmony_ci    def test_struct_cleans_up_at_runtime_shutdown(self):
6607db96d56Sopenharmony_ci        code = """if 1:
6617db96d56Sopenharmony_ci            import struct
6627db96d56Sopenharmony_ci
6637db96d56Sopenharmony_ci            class C:
6647db96d56Sopenharmony_ci                def __init__(self):
6657db96d56Sopenharmony_ci                    self.pack = struct.pack
6667db96d56Sopenharmony_ci                def __del__(self):
6677db96d56Sopenharmony_ci                    self.pack('I', -42)
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci            struct.x = C()
6707db96d56Sopenharmony_ci            """
6717db96d56Sopenharmony_ci        rc, stdout, stderr = assert_python_ok("-c", code)
6727db96d56Sopenharmony_ci        self.assertEqual(rc, 0)
6737db96d56Sopenharmony_ci        self.assertEqual(stdout.rstrip(), b"")
6747db96d56Sopenharmony_ci        self.assertIn(b"Exception ignored in:", stderr)
6757db96d56Sopenharmony_ci        self.assertIn(b"C.__del__", stderr)
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci    def test__struct_reference_cycle_cleaned_up(self):
6787db96d56Sopenharmony_ci        # Regression test for python/cpython#94207.
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci        # When we create a new struct module, trigger use of its cache,
6817db96d56Sopenharmony_ci        # and then delete it ...
6827db96d56Sopenharmony_ci        _struct_module = import_helper.import_fresh_module("_struct")
6837db96d56Sopenharmony_ci        module_ref = weakref.ref(_struct_module)
6847db96d56Sopenharmony_ci        _struct_module.calcsize("b")
6857db96d56Sopenharmony_ci        del _struct_module
6867db96d56Sopenharmony_ci
6877db96d56Sopenharmony_ci        # Then the module should have been garbage collected.
6887db96d56Sopenharmony_ci        gc.collect()
6897db96d56Sopenharmony_ci        self.assertIsNone(
6907db96d56Sopenharmony_ci            module_ref(), "_struct module was not garbage collected")
6917db96d56Sopenharmony_ci
6927db96d56Sopenharmony_ci    @support.cpython_only
6937db96d56Sopenharmony_ci    def test__struct_types_immutable(self):
6947db96d56Sopenharmony_ci        # See https://github.com/python/cpython/issues/94254
6957db96d56Sopenharmony_ci
6967db96d56Sopenharmony_ci        Struct = struct.Struct
6977db96d56Sopenharmony_ci        unpack_iterator = type(struct.iter_unpack("b", b'x'))
6987db96d56Sopenharmony_ci        for cls in (Struct, unpack_iterator):
6997db96d56Sopenharmony_ci            with self.subTest(cls=cls):
7007db96d56Sopenharmony_ci                with self.assertRaises(TypeError):
7017db96d56Sopenharmony_ci                    cls.x = 1
7027db96d56Sopenharmony_ci
7037db96d56Sopenharmony_ci
7047db96d56Sopenharmony_ci    def test_issue35714(self):
7057db96d56Sopenharmony_ci        # Embedded null characters should not be allowed in format strings.
7067db96d56Sopenharmony_ci        for s in '\0', '2\0i', b'\0':
7077db96d56Sopenharmony_ci            with self.assertRaisesRegex(struct.error,
7087db96d56Sopenharmony_ci                                        'embedded null character'):
7097db96d56Sopenharmony_ci                struct.calcsize(s)
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci    @support.cpython_only
7127db96d56Sopenharmony_ci    def test_issue45034_unsigned(self):
7137db96d56Sopenharmony_ci        _testcapi = import_helper.import_module('_testcapi')
7147db96d56Sopenharmony_ci        error_msg = f'ushort format requires 0 <= number <= {_testcapi.USHRT_MAX}'
7157db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, error_msg):
7167db96d56Sopenharmony_ci            struct.pack('H', 70000)  # too large
7177db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, error_msg):
7187db96d56Sopenharmony_ci            struct.pack('H', -1)  # too small
7197db96d56Sopenharmony_ci
7207db96d56Sopenharmony_ci    @support.cpython_only
7217db96d56Sopenharmony_ci    def test_issue45034_signed(self):
7227db96d56Sopenharmony_ci        _testcapi = import_helper.import_module('_testcapi')
7237db96d56Sopenharmony_ci        error_msg = f'short format requires {_testcapi.SHRT_MIN} <= number <= {_testcapi.SHRT_MAX}'
7247db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, error_msg):
7257db96d56Sopenharmony_ci            struct.pack('h', 70000)  # too large
7267db96d56Sopenharmony_ci        with self.assertRaisesRegex(struct.error, error_msg):
7277db96d56Sopenharmony_ci            struct.pack('h', -70000)  # too small
7287db96d56Sopenharmony_ci
7297db96d56Sopenharmony_ci
7307db96d56Sopenharmony_ciclass UnpackIteratorTest(unittest.TestCase):
7317db96d56Sopenharmony_ci    """
7327db96d56Sopenharmony_ci    Tests for iterative unpacking (struct.Struct.iter_unpack).
7337db96d56Sopenharmony_ci    """
7347db96d56Sopenharmony_ci
7357db96d56Sopenharmony_ci    def test_construct(self):
7367db96d56Sopenharmony_ci        def _check_iterator(it):
7377db96d56Sopenharmony_ci            self.assertIsInstance(it, abc.Iterator)
7387db96d56Sopenharmony_ci            self.assertIsInstance(it, abc.Iterable)
7397db96d56Sopenharmony_ci        s = struct.Struct('>ibcp')
7407db96d56Sopenharmony_ci        it = s.iter_unpack(b"")
7417db96d56Sopenharmony_ci        _check_iterator(it)
7427db96d56Sopenharmony_ci        it = s.iter_unpack(b"1234567")
7437db96d56Sopenharmony_ci        _check_iterator(it)
7447db96d56Sopenharmony_ci        # Wrong bytes length
7457db96d56Sopenharmony_ci        with self.assertRaises(struct.error):
7467db96d56Sopenharmony_ci            s.iter_unpack(b"123456")
7477db96d56Sopenharmony_ci        with self.assertRaises(struct.error):
7487db96d56Sopenharmony_ci            s.iter_unpack(b"12345678")
7497db96d56Sopenharmony_ci        # Zero-length struct
7507db96d56Sopenharmony_ci        s = struct.Struct('>')
7517db96d56Sopenharmony_ci        with self.assertRaises(struct.error):
7527db96d56Sopenharmony_ci            s.iter_unpack(b"")
7537db96d56Sopenharmony_ci        with self.assertRaises(struct.error):
7547db96d56Sopenharmony_ci            s.iter_unpack(b"12")
7557db96d56Sopenharmony_ci
7567db96d56Sopenharmony_ci    def test_uninstantiable(self):
7577db96d56Sopenharmony_ci        iter_unpack_type = type(struct.Struct(">ibcp").iter_unpack(b""))
7587db96d56Sopenharmony_ci        self.assertRaises(TypeError, iter_unpack_type)
7597db96d56Sopenharmony_ci
7607db96d56Sopenharmony_ci    def test_iterate(self):
7617db96d56Sopenharmony_ci        s = struct.Struct('>IB')
7627db96d56Sopenharmony_ci        b = bytes(range(1, 16))
7637db96d56Sopenharmony_ci        it = s.iter_unpack(b)
7647db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x01020304, 5))
7657db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x06070809, 10))
7667db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x0b0c0d0e, 15))
7677db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
7687db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
7697db96d56Sopenharmony_ci
7707db96d56Sopenharmony_ci    def test_arbitrary_buffer(self):
7717db96d56Sopenharmony_ci        s = struct.Struct('>IB')
7727db96d56Sopenharmony_ci        b = bytes(range(1, 11))
7737db96d56Sopenharmony_ci        it = s.iter_unpack(memoryview(b))
7747db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x01020304, 5))
7757db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x06070809, 10))
7767db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
7777db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
7787db96d56Sopenharmony_ci
7797db96d56Sopenharmony_ci    def test_length_hint(self):
7807db96d56Sopenharmony_ci        lh = operator.length_hint
7817db96d56Sopenharmony_ci        s = struct.Struct('>IB')
7827db96d56Sopenharmony_ci        b = bytes(range(1, 16))
7837db96d56Sopenharmony_ci        it = s.iter_unpack(b)
7847db96d56Sopenharmony_ci        self.assertEqual(lh(it), 3)
7857db96d56Sopenharmony_ci        next(it)
7867db96d56Sopenharmony_ci        self.assertEqual(lh(it), 2)
7877db96d56Sopenharmony_ci        next(it)
7887db96d56Sopenharmony_ci        self.assertEqual(lh(it), 1)
7897db96d56Sopenharmony_ci        next(it)
7907db96d56Sopenharmony_ci        self.assertEqual(lh(it), 0)
7917db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
7927db96d56Sopenharmony_ci        self.assertEqual(lh(it), 0)
7937db96d56Sopenharmony_ci
7947db96d56Sopenharmony_ci    def test_module_func(self):
7957db96d56Sopenharmony_ci        # Sanity check for the global struct.iter_unpack()
7967db96d56Sopenharmony_ci        it = struct.iter_unpack('>IB', bytes(range(1, 11)))
7977db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x01020304, 5))
7987db96d56Sopenharmony_ci        self.assertEqual(next(it), (0x06070809, 10))
7997db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
8007db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, it)
8017db96d56Sopenharmony_ci
8027db96d56Sopenharmony_ci    def test_half_float(self):
8037db96d56Sopenharmony_ci        # Little-endian examples from:
8047db96d56Sopenharmony_ci        # http://en.wikipedia.org/wiki/Half_precision_floating-point_format
8057db96d56Sopenharmony_ci        format_bits_float__cleanRoundtrip_list = [
8067db96d56Sopenharmony_ci            (b'\x00\x3c', 1.0),
8077db96d56Sopenharmony_ci            (b'\x00\xc0', -2.0),
8087db96d56Sopenharmony_ci            (b'\xff\x7b', 65504.0), #  (max half precision)
8097db96d56Sopenharmony_ci            (b'\x00\x04', 2**-14), # ~= 6.10352 * 10**-5 (min pos normal)
8107db96d56Sopenharmony_ci            (b'\x01\x00', 2**-24), # ~= 5.96046 * 10**-8 (min pos subnormal)
8117db96d56Sopenharmony_ci            (b'\x00\x00', 0.0),
8127db96d56Sopenharmony_ci            (b'\x00\x80', -0.0),
8137db96d56Sopenharmony_ci            (b'\x00\x7c', float('+inf')),
8147db96d56Sopenharmony_ci            (b'\x00\xfc', float('-inf')),
8157db96d56Sopenharmony_ci            (b'\x55\x35', 0.333251953125), # ~= 1/3
8167db96d56Sopenharmony_ci        ]
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ci        for le_bits, f in format_bits_float__cleanRoundtrip_list:
8197db96d56Sopenharmony_ci            be_bits = le_bits[::-1]
8207db96d56Sopenharmony_ci            self.assertEqual(f, struct.unpack('<e', le_bits)[0])
8217db96d56Sopenharmony_ci            self.assertEqual(le_bits, struct.pack('<e', f))
8227db96d56Sopenharmony_ci            self.assertEqual(f, struct.unpack('>e', be_bits)[0])
8237db96d56Sopenharmony_ci            self.assertEqual(be_bits, struct.pack('>e', f))
8247db96d56Sopenharmony_ci            if sys.byteorder == 'little':
8257db96d56Sopenharmony_ci                self.assertEqual(f, struct.unpack('e', le_bits)[0])
8267db96d56Sopenharmony_ci                self.assertEqual(le_bits, struct.pack('e', f))
8277db96d56Sopenharmony_ci            else:
8287db96d56Sopenharmony_ci                self.assertEqual(f, struct.unpack('e', be_bits)[0])
8297db96d56Sopenharmony_ci                self.assertEqual(be_bits, struct.pack('e', f))
8307db96d56Sopenharmony_ci
8317db96d56Sopenharmony_ci        # Check for NaN handling:
8327db96d56Sopenharmony_ci        format_bits__nan_list = [
8337db96d56Sopenharmony_ci            ('<e', b'\x01\xfc'),
8347db96d56Sopenharmony_ci            ('<e', b'\x00\xfe'),
8357db96d56Sopenharmony_ci            ('<e', b'\xff\xff'),
8367db96d56Sopenharmony_ci            ('<e', b'\x01\x7c'),
8377db96d56Sopenharmony_ci            ('<e', b'\x00\x7e'),
8387db96d56Sopenharmony_ci            ('<e', b'\xff\x7f'),
8397db96d56Sopenharmony_ci        ]
8407db96d56Sopenharmony_ci
8417db96d56Sopenharmony_ci        for formatcode, bits in format_bits__nan_list:
8427db96d56Sopenharmony_ci            self.assertTrue(math.isnan(struct.unpack('<e', bits)[0]))
8437db96d56Sopenharmony_ci            self.assertTrue(math.isnan(struct.unpack('>e', bits[::-1])[0]))
8447db96d56Sopenharmony_ci
8457db96d56Sopenharmony_ci        # Check that packing produces a bit pattern representing a quiet NaN:
8467db96d56Sopenharmony_ci        # all exponent bits and the msb of the fraction should all be 1.
8477db96d56Sopenharmony_ci        packed = struct.pack('<e', math.nan)
8487db96d56Sopenharmony_ci        self.assertEqual(packed[1] & 0x7e, 0x7e)
8497db96d56Sopenharmony_ci        packed = struct.pack('<e', -math.nan)
8507db96d56Sopenharmony_ci        self.assertEqual(packed[1] & 0x7e, 0x7e)
8517db96d56Sopenharmony_ci
8527db96d56Sopenharmony_ci        # Checks for round-to-even behavior
8537db96d56Sopenharmony_ci        format_bits_float__rounding_list = [
8547db96d56Sopenharmony_ci            ('>e', b'\x00\x01', 2.0**-25 + 2.0**-35), # Rounds to minimum subnormal
8557db96d56Sopenharmony_ci            ('>e', b'\x00\x00', 2.0**-25), # Underflows to zero (nearest even mode)
8567db96d56Sopenharmony_ci            ('>e', b'\x00\x00', 2.0**-26), # Underflows to zero
8577db96d56Sopenharmony_ci            ('>e', b'\x03\xff', 2.0**-14 - 2.0**-24), # Largest subnormal.
8587db96d56Sopenharmony_ci            ('>e', b'\x03\xff', 2.0**-14 - 2.0**-25 - 2.0**-65),
8597db96d56Sopenharmony_ci            ('>e', b'\x04\x00', 2.0**-14 - 2.0**-25),
8607db96d56Sopenharmony_ci            ('>e', b'\x04\x00', 2.0**-14), # Smallest normal.
8617db96d56Sopenharmony_ci            ('>e', b'\x3c\x01', 1.0+2.0**-11 + 2.0**-16), # rounds to 1.0+2**(-10)
8627db96d56Sopenharmony_ci            ('>e', b'\x3c\x00', 1.0+2.0**-11), # rounds to 1.0 (nearest even mode)
8637db96d56Sopenharmony_ci            ('>e', b'\x3c\x00', 1.0+2.0**-12), # rounds to 1.0
8647db96d56Sopenharmony_ci            ('>e', b'\x7b\xff', 65504), # largest normal
8657db96d56Sopenharmony_ci            ('>e', b'\x7b\xff', 65519), # rounds to 65504
8667db96d56Sopenharmony_ci            ('>e', b'\x80\x01', -2.0**-25 - 2.0**-35), # Rounds to minimum subnormal
8677db96d56Sopenharmony_ci            ('>e', b'\x80\x00', -2.0**-25), # Underflows to zero (nearest even mode)
8687db96d56Sopenharmony_ci            ('>e', b'\x80\x00', -2.0**-26), # Underflows to zero
8697db96d56Sopenharmony_ci            ('>e', b'\xbc\x01', -1.0-2.0**-11 - 2.0**-16), # rounds to 1.0+2**(-10)
8707db96d56Sopenharmony_ci            ('>e', b'\xbc\x00', -1.0-2.0**-11), # rounds to 1.0 (nearest even mode)
8717db96d56Sopenharmony_ci            ('>e', b'\xbc\x00', -1.0-2.0**-12), # rounds to 1.0
8727db96d56Sopenharmony_ci            ('>e', b'\xfb\xff', -65519), # rounds to 65504
8737db96d56Sopenharmony_ci        ]
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_ci        for formatcode, bits, f in format_bits_float__rounding_list:
8767db96d56Sopenharmony_ci            self.assertEqual(bits, struct.pack(formatcode, f))
8777db96d56Sopenharmony_ci
8787db96d56Sopenharmony_ci        # This overflows, and so raises an error
8797db96d56Sopenharmony_ci        format_bits_float__roundingError_list = [
8807db96d56Sopenharmony_ci            # Values that round to infinity.
8817db96d56Sopenharmony_ci            ('>e', 65520.0),
8827db96d56Sopenharmony_ci            ('>e', 65536.0),
8837db96d56Sopenharmony_ci            ('>e', 1e300),
8847db96d56Sopenharmony_ci            ('>e', -65520.0),
8857db96d56Sopenharmony_ci            ('>e', -65536.0),
8867db96d56Sopenharmony_ci            ('>e', -1e300),
8877db96d56Sopenharmony_ci            ('<e', 65520.0),
8887db96d56Sopenharmony_ci            ('<e', 65536.0),
8897db96d56Sopenharmony_ci            ('<e', 1e300),
8907db96d56Sopenharmony_ci            ('<e', -65520.0),
8917db96d56Sopenharmony_ci            ('<e', -65536.0),
8927db96d56Sopenharmony_ci            ('<e', -1e300),
8937db96d56Sopenharmony_ci        ]
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci        for formatcode, f in format_bits_float__roundingError_list:
8967db96d56Sopenharmony_ci            self.assertRaises(OverflowError, struct.pack, formatcode, f)
8977db96d56Sopenharmony_ci
8987db96d56Sopenharmony_ci        # Double rounding
8997db96d56Sopenharmony_ci        format_bits_float__doubleRoundingError_list = [
9007db96d56Sopenharmony_ci            ('>e', b'\x67\xff', 0x1ffdffffff * 2**-26), # should be 2047, if double-rounded 64>32>16, becomes 2048
9017db96d56Sopenharmony_ci        ]
9027db96d56Sopenharmony_ci
9037db96d56Sopenharmony_ci        for formatcode, bits, f in format_bits_float__doubleRoundingError_list:
9047db96d56Sopenharmony_ci            self.assertEqual(bits, struct.pack(formatcode, f))
9057db96d56Sopenharmony_ci
9067db96d56Sopenharmony_ci
9077db96d56Sopenharmony_ciif __name__ == '__main__':
9087db96d56Sopenharmony_ci    unittest.main()
909