10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport array
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport struct
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport inspect
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support as support
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.test_support import (check_warnings, check_py3k_warnings)
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
100a8c90248264a8b26970b4473770bcc3df8515fJosh GaoISBIGENDIAN = sys.byteorder == "big"
110a8c90248264a8b26970b4473770bcc3df8515fJosh GaoIS32BIT = sys.maxsize == 0x7fffffff
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaointeger_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q'
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotestmod_filename = os.path.splitext(__file__)[0] + '.py'
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Native 'q' packing isn't available on systems that don't have the C
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# long long type.
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    struct.pack('q', 5)
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept struct.error:
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    HAVE_LONG_LONG = False
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse:
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    HAVE_LONG_LONG = True
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef string_reverse(s):
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return "".join(reversed(s))
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef bigendian_to_native(value):
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if ISBIGENDIAN:
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return value
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return string_reverse(value)
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass StructTest(unittest.TestCase):
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def check_float_coerce(self, format, number):
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # SF bug 1530559. struct.pack raises TypeError where it used
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # to convert.
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with check_warnings((".*integer argument expected, got float",
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             DeprecationWarning)) as w:
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = struct.pack(format, number)
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        lineno = inspect.currentframe().f_lineno - 1
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(w.filename, testmod_filename)
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(w.lineno, lineno)
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(w.warnings), 1)
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = struct.pack(format, int(number))
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got, expected)
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isbigendian(self):
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((struct.pack('=i', 1)[0] == chr(0)), ISBIGENDIAN)
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_consistence(self):
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.calcsize, 'Z')
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sz = struct.calcsize('i')
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(sz * 3, struct.calcsize('iii'))
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fmt = 'cbxxxxxxhhhhiillffd?'
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fmt3 = '3c3b18x12h6i6l6f3d3?'
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sz = struct.calcsize(fmt)
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sz3 = struct.calcsize(fmt3)
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(sz * 3, sz3)
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.pack, 'iii', 3)
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.pack, 'i', 3, 3, 3)
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((TypeError, struct.error), struct.pack, 'i', 'foo')
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((TypeError, struct.error), struct.pack, 'P', 'foo')
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.unpack, 'd', 'flap')
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = struct.pack('ii', 1, 2)
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.unpack, 'iii', s)
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.unpack, 'i', s)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_transitiveness(self):
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c = 'a'
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = 1
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        h = 255
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 65535
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        l = 65536
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = 3.1415
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = 3.1415
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = True
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for prefix in ('', '@', '<', '>', '=', '!'):
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for format in ('xcbhilfd?', 'xcBHILfd?'):
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                format = prefix + format
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                s = struct.pack(format, c, b, h, i, l, f, d, t)
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s)
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(cp, c)
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(bp, b)
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(hp, h)
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(ip, i)
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(lp, l)
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(int(100 * fp), int(100 * f))
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(int(100 * dp), int(100 * d))
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(tp, t)
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_new_features(self):
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test some of the new features in detail
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # (format, argument, big-endian result, little-endian result, asymmetric)
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tests = [
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('c', 'a', 'a', 'a', 0),
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('xc', 'a', '\0a', '\0a', 0),
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('cx', 'a', 'a\0', 'a\0', 0),
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('s', 'a', 'a', 'a', 0),
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('0s', 'helloworld', '', '', 1),
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('1s', 'helloworld', 'h', 'h', 1),
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('b', 7, '\7', '\7', 0),
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('b', -7, '\371', '\371', 0),
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('B', 7, '\7', '\7', 0),
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('B', 249, '\371', '\371', 0),
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('h', 700, '\002\274', '\274\002', 0),
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('h', -700, '\375D', 'D\375', 0),
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('H', 700, '\002\274', '\274\002', 0),
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('H', 0x10000-700, '\375D', 'D\375', 0),
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('I', 70000000L, '\004,\035\200', '\200\035,\004', 0),
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('I', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('L', 70000000L, '\004,\035\200', '\200\035,\004', 0),
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('L', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('d', 2.0, '@\000\000\000\000\000\000\000',
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       '\000\000\000\000\000\000\000@', 0),
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ('d', -2.0, '\300\000\000\000\000\000\000\000',
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       '\000\000\000\000\000\000\000\300', 0),
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('?', 0, '\0', '\0', 0),
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('?', 3, '\1', '\1', 1),
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('?', True, '\1', '\1', 0),
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('?', [], '\0', '\0', 1),
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('?', (1,), '\1', '\1', 1),
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ]
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for fmt, arg, big, lil, asy in tests:
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                ('='+fmt, ISBIGENDIAN and big or lil)]:
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                res = struct.pack(xfmt, arg)
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(res, exp)
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(struct.calcsize(xfmt), len(res))
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rev = struct.unpack(xfmt, res)[0]
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if rev != arg:
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertTrue(asy)
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_calcsize(self):
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected_size = {
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'b': 1, 'B': 1,
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'h': 2, 'H': 2,
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'i': 4, 'I': 4,
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'l': 4, 'L': 4,
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'q': 8, 'Q': 8,
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            }
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # standard integer sizes
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code in integer_codes:
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for byteorder in ('=', '<', '>', '!'):
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                format = byteorder+code
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                size = struct.calcsize(format)
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(size, expected_size[code])
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # native integer sizes, except 'q' and 'Q'
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for format_pair in ('bB', 'hH', 'iI', 'lL'):
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for byteorder in ['', '@']:
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                signed_size = struct.calcsize(byteorder + format_pair[0])
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                unsigned_size = struct.calcsize(byteorder + format_pair[1])
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(signed_size, unsigned_size)
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bounds for native integer sizes
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(struct.calcsize('b'), 1)
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertLessEqual(2, struct.calcsize('h'))
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertLessEqual(4, struct.calcsize('l'))
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertLessEqual(struct.calcsize('h'), struct.calcsize('i'))
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertLessEqual(struct.calcsize('i'), struct.calcsize('l'))
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # tests for native 'q' and 'Q' when applicable
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if HAVE_LONG_LONG:
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(struct.calcsize('q'), struct.calcsize('Q'))
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertLessEqual(8, struct.calcsize('q'))
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_integers(self):
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Integer tests (bBhHiIlLqQ).
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import binascii
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class IntTester(unittest.TestCase):
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, format):
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                super(IntTester, self).__init__(methodName='test_one')
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.format = format
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.code = format[-1]
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.direction = format[:-1]
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if not self.direction in ('', '@', '=', '<', '>', '!'):
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    raise ValueError("unrecognized packing direction: %s" %
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     self.direction)
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.bytesize = struct.calcsize(format)
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.bitsize = self.bytesize * 8
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if self.code in tuple('bhilq'):
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.signed = True
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.min_value = -(2L**(self.bitsize-1))
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.max_value = 2L**(self.bitsize-1) - 1
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                elif self.code in tuple('BHILQ'):
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.signed = False
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.min_value = 0
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.max_value = 2L**self.bitsize - 1
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    raise ValueError("unrecognized format code: %s" %
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     self.code)
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def test_one(self, x, pack=struct.pack,
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  unpack=struct.unpack,
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  unhexlify=binascii.unhexlify):
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                format = self.format
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if self.min_value <= x <= self.max_value:
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = long(x)
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if self.signed and x < 0:
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected += 1L << self.bitsize
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertGreaterEqual(expected, 0)
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = '%x' % expected
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if len(expected) & 1:
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = "0" + expected
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = unhexlify(expected)
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = ("\x00" * (self.bytesize - len(expected)) +
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                expected)
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if (self.direction == '<' or
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        self.direction in ('', '@', '=') and not ISBIGENDIAN):
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = string_reverse(expected)
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(len(expected), self.bytesize)
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # Pack work?
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    got = pack(format, x)
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(got, expected)
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # Unpack work?
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    retrieved = unpack(format, got)[0]
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(x, retrieved)
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # Adding any byte should cause a "too big" error.
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertRaises((struct.error, TypeError), unpack, format,
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                                                 '\x01' + got)
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # x is out of range -- verify pack realizes that.
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertRaises((OverflowError, ValueError, struct.error),
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                      pack, format, x)
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def run(self):
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                from random import randrange
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Create all interesting powers of 2.
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                values = []
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for exp in range(self.bitsize + 3):
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    values.append(1L << exp)
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Add some random values.
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for i in range(self.bitsize):
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    val = 0L
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    for j in range(self.bytesize):
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        val = (val << 8) | randrange(256)
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    values.append(val)
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Values absorbed from other tests
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                values.extend([300, 700000, sys.maxint*4])
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Try all those, and their negations, and +-1 from
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # them.  Note that this tests all power-of-2
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # boundaries in range, and a few out of range, plus
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # +-(2**n +- 1).
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for base in values:
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    for val in -base, base:
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        for incr in -1, 0, 1:
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            x = val + incr
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            self.test_one(int(x))
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            self.test_one(long(x))
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Some error cases.
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                class NotAnIntNS(object):
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __int__(self):
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return 42
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __long__(self):
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return 1729L
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                class NotAnIntOS:
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __int__(self):
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return 85
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __long__(self):
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return -163L
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Objects with an '__index__' method should be allowed
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # to pack as integers.  That is assuming the implemented
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # '__index__' method returns and 'int' or 'long'.
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                class Indexable(object):
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __init__(self, value):
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        self._value = value
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __index__(self):
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return self._value
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # If the '__index__' method raises a type error, then
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # '__int__' should be used with a deprecation warning.
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                class BadIndex(object):
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __index__(self):
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        raise TypeError
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def __int__(self):
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return 42
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertRaises((TypeError, struct.error),
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  struct.pack, self.format,
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  "a string")
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertRaises((TypeError, struct.error),
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  struct.pack, self.format,
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  randrange)
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                with check_warnings(("integer argument expected, "
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     "got non-integer", DeprecationWarning)):
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    with self.assertRaises((TypeError, struct.error)):
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        struct.pack(self.format, 3+42j)
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # an attempt to convert a non-integer (with an
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # implicit conversion via __int__) should succeed,
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # with a DeprecationWarning
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for nonint in NotAnIntNS(), NotAnIntOS(), BadIndex():
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    with check_warnings((".*integer argument expected, got non"
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                         "-integer", DeprecationWarning)) as w:
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        got = struct.pack(self.format, nonint)
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    lineno = inspect.currentframe().f_lineno - 1
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(w.filename, testmod_filename)
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(w.lineno, lineno)
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(len(w.warnings), 1)
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = struct.pack(self.format, int(nonint))
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(got, expected)
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Check for legitimate values from '__index__'.
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for obj in (Indexable(0), Indexable(10), Indexable(17),
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            Indexable(42), Indexable(100), Indexable(127)):
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    try:
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        struct.pack(format, obj)
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    except:
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        self.fail("integer code pack failed on object "
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  "with '__index__' method")
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Check for bogus values from '__index__'.
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for obj in (Indexable('a'), Indexable(u'b'), Indexable(None),
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            Indexable({'a': 1}), Indexable([1, 2, 3])):
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertRaises((TypeError, struct.error),
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                      struct.pack, self.format,
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                      obj)
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        byteorders = '', '@', '=', '<', '>', '!'
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code in integer_codes:
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for byteorder in byteorders:
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if (byteorder in ('', '@') and code in ('q', 'Q') and
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    not HAVE_LONG_LONG):
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    continue
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                format = byteorder+code
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                t = IntTester(format)
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                t.run()
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_p_code(self):
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test p ("Pascal string") code.
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code, input, expected, expectedback in [
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('p','abc', '\x00', ''),
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('1p', 'abc', '\x00', ''),
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('2p', 'abc', '\x01a', 'a'),
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('3p', 'abc', '\x02ab', 'ab'),
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('4p', 'abc', '\x03abc', 'abc'),
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('5p', 'abc', '\x03abc\x00', 'abc'),
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('6p', 'abc', '\x03abc\x00\x00', 'abc'),
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ('1000p', 'x'*1000, '\xff' + 'x'*999, 'x'*255)]:
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = struct.pack(code, input)
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(got, expected)
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            (got,) = struct.unpack(code, got)
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(got, expectedback)
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_705836(self):
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # SF bug 705836.  "<f" and ">f" had a severe rounding bug, where a carry
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # from the low-order discarded bits could propagate into the exponent
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # field, causing the result to be wrong by a factor of 2.
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import math
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for base in range(1, 33):
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # smaller <- largest representable float less than base.
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            delta = 0.5
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            while base - delta / 2.0 != base:
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                delta /= 2.0
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            smaller = base - delta
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Packing this rounds away a solid string of trailing 1 bits.
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            packed = struct.pack("<f", smaller)
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            unpacked = struct.unpack("<f", packed)[0]
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # 16, respectively.
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(base, unpacked)
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            bigpacked = struct.pack(">f", smaller)
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(bigpacked, string_reverse(packed))
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            unpacked = struct.unpack(">f", bigpacked)[0]
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(base, unpacked)
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Largest finite IEEE single.
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        big = (1 << 24) - 1
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        big = math.ldexp(big, 127 - 23)
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        packed = struct.pack(">f", big)
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        unpacked = struct.unpack(">f", packed)[0]
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(big, unpacked)
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The same, but tack on a 1 bit so it rounds up to infinity.
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        big = (1 << 25) - 1
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        big = math.ldexp(big, 127 - 24)
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OverflowError, struct.pack, ">f", big)
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_1530559(self):
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # SF bug 1530559. struct.pack raises TypeError where it used to convert.
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for endian in ('', '>', '<'):
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for fmt in integer_codes:
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.check_float_coerce(endian + fmt, 1.0)
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.check_float_coerce(endian + fmt, 1.5)
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_unpack_from(self, cls=str):
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        data = cls('abcd01234')
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fmt = '4s'
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = struct.Struct(fmt)
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(s.unpack_from(data), ('abcd',))
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(struct.unpack_from(fmt, data), ('abcd',))
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in xrange(6):
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(s.unpack_from(data, i), (data[i:i+4],))
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],))
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in xrange(6, len(data) + 1):
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(struct.error, s.unpack_from, data, i)
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(struct.error, struct.unpack_from, fmt, data, i)
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pack_into(self):
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        test_string = 'Reykjavik rocks, eow!'
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        writable_buf = array.array('c', ' '*100)
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fmt = '21s'
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = struct.Struct(fmt)
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test without offset
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s.pack_into(writable_buf, 0, test_string)
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from_buf = writable_buf.tostring()[:len(test_string)]
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(from_buf, test_string)
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test with offset.
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s.pack_into(writable_buf, 10, test_string)
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from_buf = writable_buf.tostring()[:len(test_string)+10]
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(from_buf, test_string[:10] + test_string)
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Go beyond boundaries.
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        small_buf = array.array('c', ' '*10)
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 0,
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          test_string)
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 2,
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          test_string)
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test bogus offset (issue 3694)
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sb = small_buf
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((TypeError, struct.error), struct.pack_into, b'', sb,
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          None)
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pack_into_fn(self):
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        test_string = 'Reykjavik rocks, eow!'
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        writable_buf = array.array('c', ' '*100)
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fmt = '21s'
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pack_into = lambda *args: struct.pack_into(fmt, *args)
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test without offset.
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pack_into(writable_buf, 0, test_string)
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from_buf = writable_buf.tostring()[:len(test_string)]
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(from_buf, test_string)
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test with offset.
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pack_into(writable_buf, 10, test_string)
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from_buf = writable_buf.tostring()[:len(test_string)+10]
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(from_buf, test_string[:10] + test_string)
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Go beyond boundaries.
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        small_buf = array.array('c', ' '*10)
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((ValueError, struct.error), pack_into, small_buf, 0,
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          test_string)
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((ValueError, struct.error), pack_into, small_buf, 2,
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          test_string)
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_unpack_with_buffer(self):
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with check_py3k_warnings(("buffer.. not supported in 3.x",
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  DeprecationWarning)):
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # SF bug 1563759: struct.unpack doesn't support buffer protocol objects
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            data1 = array.array('B', '\x12\x34\x56\x78')
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            data2 = buffer('......\x12\x34\x56\x78......', 6, 4)
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for data in [data1, data2]:
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                value, = struct.unpack('>I', data)
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(value, 0x12345678)
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.test_unpack_from(cls=buffer)
4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_unpack_with_memoryview(self):
5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Bug 10212: struct.unpack doesn't support new buffer protocol objects
5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        data1 = memoryview('\x12\x34\x56\x78')
5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for data in [data1,]:
5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            value, = struct.unpack('>I', data)
5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(value, 0x12345678)
5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.test_unpack_from(cls=memoryview)
5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bool(self):
5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class ExplodingBool(object):
5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __nonzero__(self):
5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise IOError
5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for prefix in tuple("<>!=")+('',):
5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            false = (), [], [], '', 0
5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            true = [1], 'test', 5, -1, 0xffffffffL+1, 0xffffffff//2
5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            falseFormat = prefix + '?' * len(false)
5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            packedFalse = struct.pack(falseFormat, *false)
5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            unpackedFalse = struct.unpack(falseFormat, packedFalse)
5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            trueFormat = prefix + '?' * len(true)
5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            packedTrue = struct.pack(trueFormat, *true)
5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            unpackedTrue = struct.unpack(trueFormat, packedTrue)
5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(len(true), len(unpackedTrue))
5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(len(false), len(unpackedFalse))
5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for t in unpackedFalse:
5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertFalse(t)
5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for t in unpackedTrue:
5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertTrue(t)
5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            packed = struct.pack(prefix+'?', 1)
5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(len(packed), struct.calcsize(prefix+'?'))
5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if len(packed) != 1:
5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertFalse(prefix, msg='encoded bool is not one byte: %r'
5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                             %packed)
5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(IOError, struct.pack, prefix + '?',
5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              ExplodingBool())
5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(struct.unpack('>?', c)[0])
5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipUnless(IS32BIT, "Specific to 32bit machines")
5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_crasher(self):
5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(MemoryError, struct.pack, "357913941c", "a")
5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_count_overflow(self):
5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        hugecount = '{}b'.format(sys.maxsize+1)
5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.calcsize, hugecount)
5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2)
5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(struct.error, struct.calcsize, hugecount2)
5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def check_sizeof(self, format_str, number_of_codes):
5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The size of 'PyStructObject'
5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        totalsize = support.calcobjsize('5P')
5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The size taken up by the 'formatcode' dynamic array
5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        totalsize += struct.calcsize('3P') * (number_of_codes + 1)
5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        support.check_sizeof(self, struct.Struct(format_str), totalsize)
5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @support.cpython_only
5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test__sizeof__(self):
5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code in integer_codes:
5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.check_sizeof(code, 1)
5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('BHILfdspP', 9)
5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('B' * 1234, 1234)
5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('fd', 2)
5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('xxxxxxxxxxxxxx', 0)
5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('100H', 100)
5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('187s', 1)
5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('20p', 1)
5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('0s', 1)
5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_sizeof('0c', 0)
5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main():
5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    support.run_unittest(StructTest)
5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
582