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