ยปCore Development>Code coverage>Lib/test/test_struct.py

Python code coverage for Lib/test/test_struct.py

#countcontent
1n/afrom collections import abc
2n/aimport array
3n/aimport math
4n/aimport operator
5n/aimport unittest
6n/aimport struct
7n/aimport sys
8n/a
9n/afrom test import support
10n/a
11n/aISBIGENDIAN = sys.byteorder == "big"
12n/a
13n/ainteger_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'n', 'N'
14n/abyteorders = '', '@', '=', '<', '>', '!'
15n/a
16n/adef iter_integer_formats(byteorders=byteorders):
17n/a for code in integer_codes:
18n/a for byteorder in byteorders:
19n/a if (byteorder not in ('', '@') and code in ('n', 'N')):
20n/a continue
21n/a yield code, byteorder
22n/a
23n/adef string_reverse(s):
24n/a return s[::-1]
25n/a
26n/adef bigendian_to_native(value):
27n/a if ISBIGENDIAN:
28n/a return value
29n/a else:
30n/a return string_reverse(value)
31n/a
32n/aclass StructTest(unittest.TestCase):
33n/a def test_isbigendian(self):
34n/a self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN)
35n/a
36n/a def test_consistence(self):
37n/a self.assertRaises(struct.error, struct.calcsize, 'Z')
38n/a
39n/a sz = struct.calcsize('i')
40n/a self.assertEqual(sz * 3, struct.calcsize('iii'))
41n/a
42n/a fmt = 'cbxxxxxxhhhhiillffd?'
43n/a fmt3 = '3c3b18x12h6i6l6f3d3?'
44n/a sz = struct.calcsize(fmt)
45n/a sz3 = struct.calcsize(fmt3)
46n/a self.assertEqual(sz * 3, sz3)
47n/a
48n/a self.assertRaises(struct.error, struct.pack, 'iii', 3)
49n/a self.assertRaises(struct.error, struct.pack, 'i', 3, 3, 3)
50n/a self.assertRaises((TypeError, struct.error), struct.pack, 'i', 'foo')
51n/a self.assertRaises((TypeError, struct.error), struct.pack, 'P', 'foo')
52n/a self.assertRaises(struct.error, struct.unpack, 'd', b'flap')
53n/a s = struct.pack('ii', 1, 2)
54n/a self.assertRaises(struct.error, struct.unpack, 'iii', s)
55n/a self.assertRaises(struct.error, struct.unpack, 'i', s)
56n/a
57n/a def test_transitiveness(self):
58n/a c = b'a'
59n/a b = 1
60n/a h = 255
61n/a i = 65535
62n/a l = 65536
63n/a f = 3.1415
64n/a d = 3.1415
65n/a t = True
66n/a
67n/a for prefix in ('', '@', '<', '>', '=', '!'):
68n/a for format in ('xcbhilfd?', 'xcBHILfd?'):
69n/a format = prefix + format
70n/a s = struct.pack(format, c, b, h, i, l, f, d, t)
71n/a cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s)
72n/a self.assertEqual(cp, c)
73n/a self.assertEqual(bp, b)
74n/a self.assertEqual(hp, h)
75n/a self.assertEqual(ip, i)
76n/a self.assertEqual(lp, l)
77n/a self.assertEqual(int(100 * fp), int(100 * f))
78n/a self.assertEqual(int(100 * dp), int(100 * d))
79n/a self.assertEqual(tp, t)
80n/a
81n/a def test_new_features(self):
82n/a # Test some of the new features in detail
83n/a # (format, argument, big-endian result, little-endian result, asymmetric)
84n/a tests = [
85n/a ('c', b'a', b'a', b'a', 0),
86n/a ('xc', b'a', b'\0a', b'\0a', 0),
87n/a ('cx', b'a', b'a\0', b'a\0', 0),
88n/a ('s', b'a', b'a', b'a', 0),
89n/a ('0s', b'helloworld', b'', b'', 1),
90n/a ('1s', b'helloworld', b'h', b'h', 1),
91n/a ('9s', b'helloworld', b'helloworl', b'helloworl', 1),
92n/a ('10s', b'helloworld', b'helloworld', b'helloworld', 0),
93n/a ('11s', b'helloworld', b'helloworld\0', b'helloworld\0', 1),
94n/a ('20s', b'helloworld', b'helloworld'+10*b'\0', b'helloworld'+10*b'\0', 1),
95n/a ('b', 7, b'\7', b'\7', 0),
96n/a ('b', -7, b'\371', b'\371', 0),
97n/a ('B', 7, b'\7', b'\7', 0),
98n/a ('B', 249, b'\371', b'\371', 0),
99n/a ('h', 700, b'\002\274', b'\274\002', 0),
100n/a ('h', -700, b'\375D', b'D\375', 0),
101n/a ('H', 700, b'\002\274', b'\274\002', 0),
102n/a ('H', 0x10000-700, b'\375D', b'D\375', 0),
103n/a ('i', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
104n/a ('i', -70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
105n/a ('I', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
106n/a ('I', 0x100000000-70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
107n/a ('l', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
108n/a ('l', -70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
109n/a ('L', 70000000, b'\004,\035\200', b'\200\035,\004', 0),
110n/a ('L', 0x100000000-70000000, b'\373\323\342\200', b'\200\342\323\373', 0),
111n/a ('f', 2.0, b'@\000\000\000', b'\000\000\000@', 0),
112n/a ('d', 2.0, b'@\000\000\000\000\000\000\000',
113n/a b'\000\000\000\000\000\000\000@', 0),
114n/a ('f', -2.0, b'\300\000\000\000', b'\000\000\000\300', 0),
115n/a ('d', -2.0, b'\300\000\000\000\000\000\000\000',
116n/a b'\000\000\000\000\000\000\000\300', 0),
117n/a ('?', 0, b'\0', b'\0', 0),
118n/a ('?', 3, b'\1', b'\1', 1),
119n/a ('?', True, b'\1', b'\1', 0),
120n/a ('?', [], b'\0', b'\0', 1),
121n/a ('?', (1,), b'\1', b'\1', 1),
122n/a ]
123n/a
124n/a for fmt, arg, big, lil, asy in tests:
125n/a for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
126n/a ('='+fmt, ISBIGENDIAN and big or lil)]:
127n/a res = struct.pack(xfmt, arg)
128n/a self.assertEqual(res, exp)
129n/a self.assertEqual(struct.calcsize(xfmt), len(res))
130n/a rev = struct.unpack(xfmt, res)[0]
131n/a if rev != arg:
132n/a self.assertTrue(asy)
133n/a
134n/a def test_calcsize(self):
135n/a expected_size = {
136n/a 'b': 1, 'B': 1,
137n/a 'h': 2, 'H': 2,
138n/a 'i': 4, 'I': 4,
139n/a 'l': 4, 'L': 4,
140n/a 'q': 8, 'Q': 8,
141n/a }
142n/a
143n/a # standard integer sizes
144n/a for code, byteorder in iter_integer_formats(('=', '<', '>', '!')):
145n/a format = byteorder+code
146n/a size = struct.calcsize(format)
147n/a self.assertEqual(size, expected_size[code])
148n/a
149n/a # native integer sizes
150n/a native_pairs = 'bB', 'hH', 'iI', 'lL', 'nN', 'qQ'
151n/a for format_pair in native_pairs:
152n/a for byteorder in '', '@':
153n/a signed_size = struct.calcsize(byteorder + format_pair[0])
154n/a unsigned_size = struct.calcsize(byteorder + format_pair[1])
155n/a self.assertEqual(signed_size, unsigned_size)
156n/a
157n/a # bounds for native integer sizes
158n/a self.assertEqual(struct.calcsize('b'), 1)
159n/a self.assertLessEqual(2, struct.calcsize('h'))
160n/a self.assertLessEqual(4, struct.calcsize('l'))
161n/a self.assertLessEqual(struct.calcsize('h'), struct.calcsize('i'))
162n/a self.assertLessEqual(struct.calcsize('i'), struct.calcsize('l'))
163n/a self.assertLessEqual(8, struct.calcsize('q'))
164n/a self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))
165n/a self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('i'))
166n/a self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('P'))
167n/a
168n/a def test_integers(self):
169n/a # Integer tests (bBhHiIlLqQnN).
170n/a import binascii
171n/a
172n/a class IntTester(unittest.TestCase):
173n/a def __init__(self, format):
174n/a super(IntTester, self).__init__(methodName='test_one')
175n/a self.format = format
176n/a self.code = format[-1]
177n/a self.byteorder = format[:-1]
178n/a if not self.byteorder in byteorders:
179n/a raise ValueError("unrecognized packing byteorder: %s" %
180n/a self.byteorder)
181n/a self.bytesize = struct.calcsize(format)
182n/a self.bitsize = self.bytesize * 8
183n/a if self.code in tuple('bhilqn'):
184n/a self.signed = True
185n/a self.min_value = -(2**(self.bitsize-1))
186n/a self.max_value = 2**(self.bitsize-1) - 1
187n/a elif self.code in tuple('BHILQN'):
188n/a self.signed = False
189n/a self.min_value = 0
190n/a self.max_value = 2**self.bitsize - 1
191n/a else:
192n/a raise ValueError("unrecognized format code: %s" %
193n/a self.code)
194n/a
195n/a def test_one(self, x, pack=struct.pack,
196n/a unpack=struct.unpack,
197n/a unhexlify=binascii.unhexlify):
198n/a
199n/a format = self.format
200n/a if self.min_value <= x <= self.max_value:
201n/a expected = x
202n/a if self.signed and x < 0:
203n/a expected += 1 << self.bitsize
204n/a self.assertGreaterEqual(expected, 0)
205n/a expected = '%x' % expected
206n/a if len(expected) & 1:
207n/a expected = "0" + expected
208n/a expected = expected.encode('ascii')
209n/a expected = unhexlify(expected)
210n/a expected = (b"\x00" * (self.bytesize - len(expected)) +
211n/a expected)
212n/a if (self.byteorder == '<' or
213n/a self.byteorder in ('', '@', '=') and not ISBIGENDIAN):
214n/a expected = string_reverse(expected)
215n/a self.assertEqual(len(expected), self.bytesize)
216n/a
217n/a # Pack work?
218n/a got = pack(format, x)
219n/a self.assertEqual(got, expected)
220n/a
221n/a # Unpack work?
222n/a retrieved = unpack(format, got)[0]
223n/a self.assertEqual(x, retrieved)
224n/a
225n/a # Adding any byte should cause a "too big" error.
226n/a self.assertRaises((struct.error, TypeError), unpack, format,
227n/a b'\x01' + got)
228n/a else:
229n/a # x is out of range -- verify pack realizes that.
230n/a self.assertRaises((OverflowError, ValueError, struct.error),
231n/a pack, format, x)
232n/a
233n/a def run(self):
234n/a from random import randrange
235n/a
236n/a # Create all interesting powers of 2.
237n/a values = []
238n/a for exp in range(self.bitsize + 3):
239n/a values.append(1 << exp)
240n/a
241n/a # Add some random values.
242n/a for i in range(self.bitsize):
243n/a val = 0
244n/a for j in range(self.bytesize):
245n/a val = (val << 8) | randrange(256)
246n/a values.append(val)
247n/a
248n/a # Values absorbed from other tests
249n/a values.extend([300, 700000, sys.maxsize*4])
250n/a
251n/a # Try all those, and their negations, and +-1 from
252n/a # them. Note that this tests all power-of-2
253n/a # boundaries in range, and a few out of range, plus
254n/a # +-(2**n +- 1).
255n/a for base in values:
256n/a for val in -base, base:
257n/a for incr in -1, 0, 1:
258n/a x = val + incr
259n/a self.test_one(x)
260n/a
261n/a # Some error cases.
262n/a class NotAnInt:
263n/a def __int__(self):
264n/a return 42
265n/a
266n/a # Objects with an '__index__' method should be allowed
267n/a # to pack as integers. That is assuming the implemented
268n/a # '__index__' method returns an 'int'.
269n/a class Indexable(object):
270n/a def __init__(self, value):
271n/a self._value = value
272n/a
273n/a def __index__(self):
274n/a return self._value
275n/a
276n/a # If the '__index__' method raises a type error, then
277n/a # '__int__' should be used with a deprecation warning.
278n/a class BadIndex(object):
279n/a def __index__(self):
280n/a raise TypeError
281n/a
282n/a def __int__(self):
283n/a return 42
284n/a
285n/a self.assertRaises((TypeError, struct.error),
286n/a struct.pack, self.format,
287n/a "a string")
288n/a self.assertRaises((TypeError, struct.error),
289n/a struct.pack, self.format,
290n/a randrange)
291n/a self.assertRaises((TypeError, struct.error),
292n/a struct.pack, self.format,
293n/a 3+42j)
294n/a self.assertRaises((TypeError, struct.error),
295n/a struct.pack, self.format,
296n/a NotAnInt())
297n/a self.assertRaises((TypeError, struct.error),
298n/a struct.pack, self.format,
299n/a BadIndex())
300n/a
301n/a # Check for legitimate values from '__index__'.
302n/a for obj in (Indexable(0), Indexable(10), Indexable(17),
303n/a Indexable(42), Indexable(100), Indexable(127)):
304n/a try:
305n/a struct.pack(format, obj)
306n/a except:
307n/a self.fail("integer code pack failed on object "
308n/a "with '__index__' method")
309n/a
310n/a # Check for bogus values from '__index__'.
311n/a for obj in (Indexable(b'a'), Indexable('b'), Indexable(None),
312n/a Indexable({'a': 1}), Indexable([1, 2, 3])):
313n/a self.assertRaises((TypeError, struct.error),
314n/a struct.pack, self.format,
315n/a obj)
316n/a
317n/a for code, byteorder in iter_integer_formats():
318n/a format = byteorder+code
319n/a t = IntTester(format)
320n/a t.run()
321n/a
322n/a def test_nN_code(self):
323n/a # n and N don't exist in standard sizes
324n/a def assertStructError(func, *args, **kwargs):
325n/a with self.assertRaises(struct.error) as cm:
326n/a func(*args, **kwargs)
327n/a self.assertIn("bad char in struct format", str(cm.exception))
328n/a for code in 'nN':
329n/a for byteorder in ('=', '<', '>', '!'):
330n/a format = byteorder+code
331n/a assertStructError(struct.calcsize, format)
332n/a assertStructError(struct.pack, format, 0)
333n/a assertStructError(struct.unpack, format, b"")
334n/a
335n/a def test_p_code(self):
336n/a # Test p ("Pascal string") code.
337n/a for code, input, expected, expectedback in [
338n/a ('p', b'abc', b'\x00', b''),
339n/a ('1p', b'abc', b'\x00', b''),
340n/a ('2p', b'abc', b'\x01a', b'a'),
341n/a ('3p', b'abc', b'\x02ab', b'ab'),
342n/a ('4p', b'abc', b'\x03abc', b'abc'),
343n/a ('5p', b'abc', b'\x03abc\x00', b'abc'),
344n/a ('6p', b'abc', b'\x03abc\x00\x00', b'abc'),
345n/a ('1000p', b'x'*1000, b'\xff' + b'x'*999, b'x'*255)]:
346n/a got = struct.pack(code, input)
347n/a self.assertEqual(got, expected)
348n/a (got,) = struct.unpack(code, got)
349n/a self.assertEqual(got, expectedback)
350n/a
351n/a def test_705836(self):
352n/a # SF bug 705836. "<f" and ">f" had a severe rounding bug, where a carry
353n/a # from the low-order discarded bits could propagate into the exponent
354n/a # field, causing the result to be wrong by a factor of 2.
355n/a for base in range(1, 33):
356n/a # smaller <- largest representable float less than base.
357n/a delta = 0.5
358n/a while base - delta / 2.0 != base:
359n/a delta /= 2.0
360n/a smaller = base - delta
361n/a # Packing this rounds away a solid string of trailing 1 bits.
362n/a packed = struct.pack("<f", smaller)
363n/a unpacked = struct.unpack("<f", packed)[0]
364n/a # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
365n/a # 16, respectively.
366n/a self.assertEqual(base, unpacked)
367n/a bigpacked = struct.pack(">f", smaller)
368n/a self.assertEqual(bigpacked, string_reverse(packed))
369n/a unpacked = struct.unpack(">f", bigpacked)[0]
370n/a self.assertEqual(base, unpacked)
371n/a
372n/a # Largest finite IEEE single.
373n/a big = (1 << 24) - 1
374n/a big = math.ldexp(big, 127 - 23)
375n/a packed = struct.pack(">f", big)
376n/a unpacked = struct.unpack(">f", packed)[0]
377n/a self.assertEqual(big, unpacked)
378n/a
379n/a # The same, but tack on a 1 bit so it rounds up to infinity.
380n/a big = (1 << 25) - 1
381n/a big = math.ldexp(big, 127 - 24)
382n/a self.assertRaises(OverflowError, struct.pack, ">f", big)
383n/a
384n/a def test_1530559(self):
385n/a for code, byteorder in iter_integer_formats():
386n/a format = byteorder + code
387n/a self.assertRaises(struct.error, struct.pack, format, 1.0)
388n/a self.assertRaises(struct.error, struct.pack, format, 1.5)
389n/a self.assertRaises(struct.error, struct.pack, 'P', 1.0)
390n/a self.assertRaises(struct.error, struct.pack, 'P', 1.5)
391n/a
392n/a def test_unpack_from(self):
393n/a test_string = b'abcd01234'
394n/a fmt = '4s'
395n/a s = struct.Struct(fmt)
396n/a for cls in (bytes, bytearray):
397n/a data = cls(test_string)
398n/a self.assertEqual(s.unpack_from(data), (b'abcd',))
399n/a self.assertEqual(s.unpack_from(data, 2), (b'cd01',))
400n/a self.assertEqual(s.unpack_from(data, 4), (b'0123',))
401n/a for i in range(6):
402n/a self.assertEqual(s.unpack_from(data, i), (data[i:i+4],))
403n/a for i in range(6, len(test_string) + 1):
404n/a self.assertRaises(struct.error, s.unpack_from, data, i)
405n/a for cls in (bytes, bytearray):
406n/a data = cls(test_string)
407n/a self.assertEqual(struct.unpack_from(fmt, data), (b'abcd',))
408n/a self.assertEqual(struct.unpack_from(fmt, data, 2), (b'cd01',))
409n/a self.assertEqual(struct.unpack_from(fmt, data, 4), (b'0123',))
410n/a for i in range(6):
411n/a self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],))
412n/a for i in range(6, len(test_string) + 1):
413n/a self.assertRaises(struct.error, struct.unpack_from, fmt, data, i)
414n/a
415n/a # keyword arguments
416n/a self.assertEqual(s.unpack_from(buffer=test_string, offset=2),
417n/a (b'cd01',))
418n/a
419n/a def test_pack_into(self):
420n/a test_string = b'Reykjavik rocks, eow!'
421n/a writable_buf = array.array('b', b' '*100)
422n/a fmt = '21s'
423n/a s = struct.Struct(fmt)
424n/a
425n/a # Test without offset
426n/a s.pack_into(writable_buf, 0, test_string)
427n/a from_buf = writable_buf.tobytes()[:len(test_string)]
428n/a self.assertEqual(from_buf, test_string)
429n/a
430n/a # Test with offset.
431n/a s.pack_into(writable_buf, 10, test_string)
432n/a from_buf = writable_buf.tobytes()[:len(test_string)+10]
433n/a self.assertEqual(from_buf, test_string[:10] + test_string)
434n/a
435n/a # Go beyond boundaries.
436n/a small_buf = array.array('b', b' '*10)
437n/a self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 0,
438n/a test_string)
439n/a self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 2,
440n/a test_string)
441n/a
442n/a # Test bogus offset (issue 3694)
443n/a sb = small_buf
444n/a self.assertRaises((TypeError, struct.error), struct.pack_into, b'', sb,
445n/a None)
446n/a
447n/a def test_pack_into_fn(self):
448n/a test_string = b'Reykjavik rocks, eow!'
449n/a writable_buf = array.array('b', b' '*100)
450n/a fmt = '21s'
451n/a pack_into = lambda *args: struct.pack_into(fmt, *args)
452n/a
453n/a # Test without offset.
454n/a pack_into(writable_buf, 0, test_string)
455n/a from_buf = writable_buf.tobytes()[:len(test_string)]
456n/a self.assertEqual(from_buf, test_string)
457n/a
458n/a # Test with offset.
459n/a pack_into(writable_buf, 10, test_string)
460n/a from_buf = writable_buf.tobytes()[:len(test_string)+10]
461n/a self.assertEqual(from_buf, test_string[:10] + test_string)
462n/a
463n/a # Go beyond boundaries.
464n/a small_buf = array.array('b', b' '*10)
465n/a self.assertRaises((ValueError, struct.error), pack_into, small_buf, 0,
466n/a test_string)
467n/a self.assertRaises((ValueError, struct.error), pack_into, small_buf, 2,
468n/a test_string)
469n/a
470n/a def test_unpack_with_buffer(self):
471n/a # SF bug 1563759: struct.unpack doesn't support buffer protocol objects
472n/a data1 = array.array('B', b'\x12\x34\x56\x78')
473n/a data2 = memoryview(b'\x12\x34\x56\x78') # XXX b'......XXXX......', 6, 4
474n/a for data in [data1, data2]:
475n/a value, = struct.unpack('>I', data)
476n/a self.assertEqual(value, 0x12345678)
477n/a
478n/a def test_bool(self):
479n/a class ExplodingBool(object):
480n/a def __bool__(self):
481n/a raise OSError
482n/a for prefix in tuple("<>!=")+('',):
483n/a false = (), [], [], '', 0
484n/a true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2
485n/a
486n/a falseFormat = prefix + '?' * len(false)
487n/a packedFalse = struct.pack(falseFormat, *false)
488n/a unpackedFalse = struct.unpack(falseFormat, packedFalse)
489n/a
490n/a trueFormat = prefix + '?' * len(true)
491n/a packedTrue = struct.pack(trueFormat, *true)
492n/a unpackedTrue = struct.unpack(trueFormat, packedTrue)
493n/a
494n/a self.assertEqual(len(true), len(unpackedTrue))
495n/a self.assertEqual(len(false), len(unpackedFalse))
496n/a
497n/a for t in unpackedFalse:
498n/a self.assertFalse(t)
499n/a for t in unpackedTrue:
500n/a self.assertTrue(t)
501n/a
502n/a packed = struct.pack(prefix+'?', 1)
503n/a
504n/a self.assertEqual(len(packed), struct.calcsize(prefix+'?'))
505n/a
506n/a if len(packed) != 1:
507n/a self.assertFalse(prefix, msg='encoded bool is not one byte: %r'
508n/a %packed)
509n/a
510n/a try:
511n/a struct.pack(prefix + '?', ExplodingBool())
512n/a except OSError:
513n/a pass
514n/a else:
515n/a self.fail("Expected OSError: struct.pack(%r, "
516n/a "ExplodingBool())" % (prefix + '?'))
517n/a
518n/a for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
519n/a self.assertTrue(struct.unpack('>?', c)[0])
520n/a
521n/a def test_count_overflow(self):
522n/a hugecount = '{}b'.format(sys.maxsize+1)
523n/a self.assertRaises(struct.error, struct.calcsize, hugecount)
524n/a
525n/a hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2)
526n/a self.assertRaises(struct.error, struct.calcsize, hugecount2)
527n/a
528n/a def test_trailing_counter(self):
529n/a store = array.array('b', b' '*100)
530n/a
531n/a # format lists containing only count spec should result in an error
532n/a self.assertRaises(struct.error, struct.pack, '12345')
533n/a self.assertRaises(struct.error, struct.unpack, '12345', b'')
534n/a self.assertRaises(struct.error, struct.pack_into, '12345', store, 0)
535n/a self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0)
536n/a
537n/a # Format lists with trailing count spec should result in an error
538n/a self.assertRaises(struct.error, struct.pack, 'c12345', 'x')
539n/a self.assertRaises(struct.error, struct.unpack, 'c12345', b'x')
540n/a self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0,
541n/a 'x')
542n/a self.assertRaises(struct.error, struct.unpack_from, 'c12345', store,
543n/a 0)
544n/a
545n/a # Mixed format tests
546n/a self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs')
547n/a self.assertRaises(struct.error, struct.unpack, '14s42',
548n/a b'spam and eggs')
549n/a self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0,
550n/a 'spam and eggs')
551n/a self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0)
552n/a
553n/a def test_Struct_reinitialization(self):
554n/a # Issue 9422: there was a memory leak when reinitializing a
555n/a # Struct instance. This test can be used to detect the leak
556n/a # when running with regrtest -L.
557n/a s = struct.Struct('i')
558n/a s.__init__('ii')
559n/a
560n/a def check_sizeof(self, format_str, number_of_codes):
561n/a # The size of 'PyStructObject'
562n/a totalsize = support.calcobjsize('2n3P')
563n/a # The size taken up by the 'formatcode' dynamic array
564n/a totalsize += struct.calcsize('P3n0P') * (number_of_codes + 1)
565n/a support.check_sizeof(self, struct.Struct(format_str), totalsize)
566n/a
567n/a @support.cpython_only
568n/a def test__sizeof__(self):
569n/a for code in integer_codes:
570n/a self.check_sizeof(code, 1)
571n/a self.check_sizeof('BHILfdspP', 9)
572n/a self.check_sizeof('B' * 1234, 1234)
573n/a self.check_sizeof('fd', 2)
574n/a self.check_sizeof('xxxxxxxxxxxxxx', 0)
575n/a self.check_sizeof('100H', 1)
576n/a self.check_sizeof('187s', 1)
577n/a self.check_sizeof('20p', 1)
578n/a self.check_sizeof('0s', 1)
579n/a self.check_sizeof('0c', 0)
580n/a
581n/a
582n/aclass UnpackIteratorTest(unittest.TestCase):
583n/a """
584n/a Tests for iterative unpacking (struct.Struct.iter_unpack).
585n/a """
586n/a
587n/a def test_construct(self):
588n/a def _check_iterator(it):
589n/a self.assertIsInstance(it, abc.Iterator)
590n/a self.assertIsInstance(it, abc.Iterable)
591n/a s = struct.Struct('>ibcp')
592n/a it = s.iter_unpack(b"")
593n/a _check_iterator(it)
594n/a it = s.iter_unpack(b"1234567")
595n/a _check_iterator(it)
596n/a # Wrong bytes length
597n/a with self.assertRaises(struct.error):
598n/a s.iter_unpack(b"123456")
599n/a with self.assertRaises(struct.error):
600n/a s.iter_unpack(b"12345678")
601n/a # Zero-length struct
602n/a s = struct.Struct('>')
603n/a with self.assertRaises(struct.error):
604n/a s.iter_unpack(b"")
605n/a with self.assertRaises(struct.error):
606n/a s.iter_unpack(b"12")
607n/a
608n/a def test_iterate(self):
609n/a s = struct.Struct('>IB')
610n/a b = bytes(range(1, 16))
611n/a it = s.iter_unpack(b)
612n/a self.assertEqual(next(it), (0x01020304, 5))
613n/a self.assertEqual(next(it), (0x06070809, 10))
614n/a self.assertEqual(next(it), (0x0b0c0d0e, 15))
615n/a self.assertRaises(StopIteration, next, it)
616n/a self.assertRaises(StopIteration, next, it)
617n/a
618n/a def test_arbitrary_buffer(self):
619n/a s = struct.Struct('>IB')
620n/a b = bytes(range(1, 11))
621n/a it = s.iter_unpack(memoryview(b))
622n/a self.assertEqual(next(it), (0x01020304, 5))
623n/a self.assertEqual(next(it), (0x06070809, 10))
624n/a self.assertRaises(StopIteration, next, it)
625n/a self.assertRaises(StopIteration, next, it)
626n/a
627n/a def test_length_hint(self):
628n/a lh = operator.length_hint
629n/a s = struct.Struct('>IB')
630n/a b = bytes(range(1, 16))
631n/a it = s.iter_unpack(b)
632n/a self.assertEqual(lh(it), 3)
633n/a next(it)
634n/a self.assertEqual(lh(it), 2)
635n/a next(it)
636n/a self.assertEqual(lh(it), 1)
637n/a next(it)
638n/a self.assertEqual(lh(it), 0)
639n/a self.assertRaises(StopIteration, next, it)
640n/a self.assertEqual(lh(it), 0)
641n/a
642n/a def test_module_func(self):
643n/a # Sanity check for the global struct.iter_unpack()
644n/a it = struct.iter_unpack('>IB', bytes(range(1, 11)))
645n/a self.assertEqual(next(it), (0x01020304, 5))
646n/a self.assertEqual(next(it), (0x06070809, 10))
647n/a self.assertRaises(StopIteration, next, it)
648n/a self.assertRaises(StopIteration, next, it)
649n/a
650n/a def test_half_float(self):
651n/a # Little-endian examples from:
652n/a # http://en.wikipedia.org/wiki/Half_precision_floating-point_format
653n/a format_bits_float__cleanRoundtrip_list = [
654n/a (b'\x00\x3c', 1.0),
655n/a (b'\x00\xc0', -2.0),
656n/a (b'\xff\x7b', 65504.0), # (max half precision)
657n/a (b'\x00\x04', 2**-14), # ~= 6.10352 * 10**-5 (min pos normal)
658n/a (b'\x01\x00', 2**-24), # ~= 5.96046 * 10**-8 (min pos subnormal)
659n/a (b'\x00\x00', 0.0),
660n/a (b'\x00\x80', -0.0),
661n/a (b'\x00\x7c', float('+inf')),
662n/a (b'\x00\xfc', float('-inf')),
663n/a (b'\x55\x35', 0.333251953125), # ~= 1/3
664n/a ]
665n/a
666n/a for le_bits, f in format_bits_float__cleanRoundtrip_list:
667n/a be_bits = le_bits[::-1]
668n/a self.assertEqual(f, struct.unpack('<e', le_bits)[0])
669n/a self.assertEqual(le_bits, struct.pack('<e', f))
670n/a self.assertEqual(f, struct.unpack('>e', be_bits)[0])
671n/a self.assertEqual(be_bits, struct.pack('>e', f))
672n/a if sys.byteorder == 'little':
673n/a self.assertEqual(f, struct.unpack('e', le_bits)[0])
674n/a self.assertEqual(le_bits, struct.pack('e', f))
675n/a else:
676n/a self.assertEqual(f, struct.unpack('e', be_bits)[0])
677n/a self.assertEqual(be_bits, struct.pack('e', f))
678n/a
679n/a # Check for NaN handling:
680n/a format_bits__nan_list = [
681n/a ('<e', b'\x01\xfc'),
682n/a ('<e', b'\x00\xfe'),
683n/a ('<e', b'\xff\xff'),
684n/a ('<e', b'\x01\x7c'),
685n/a ('<e', b'\x00\x7e'),
686n/a ('<e', b'\xff\x7f'),
687n/a ]
688n/a
689n/a for formatcode, bits in format_bits__nan_list:
690n/a self.assertTrue(math.isnan(struct.unpack('<e', bits)[0]))
691n/a self.assertTrue(math.isnan(struct.unpack('>e', bits[::-1])[0]))
692n/a
693n/a # Check that packing produces a bit pattern representing a quiet NaN:
694n/a # all exponent bits and the msb of the fraction should all be 1.
695n/a packed = struct.pack('<e', math.nan)
696n/a self.assertEqual(packed[1] & 0x7e, 0x7e)
697n/a packed = struct.pack('<e', -math.nan)
698n/a self.assertEqual(packed[1] & 0x7e, 0x7e)
699n/a
700n/a # Checks for round-to-even behavior
701n/a format_bits_float__rounding_list = [
702n/a ('>e', b'\x00\x01', 2.0**-25 + 2.0**-35), # Rounds to minimum subnormal
703n/a ('>e', b'\x00\x00', 2.0**-25), # Underflows to zero (nearest even mode)
704n/a ('>e', b'\x00\x00', 2.0**-26), # Underflows to zero
705n/a ('>e', b'\x03\xff', 2.0**-14 - 2.0**-24), # Largest subnormal.
706n/a ('>e', b'\x03\xff', 2.0**-14 - 2.0**-25 - 2.0**-65),
707n/a ('>e', b'\x04\x00', 2.0**-14 - 2.0**-25),
708n/a ('>e', b'\x04\x00', 2.0**-14), # Smallest normal.
709n/a ('>e', b'\x3c\x01', 1.0+2.0**-11 + 2.0**-16), # rounds to 1.0+2**(-10)
710n/a ('>e', b'\x3c\x00', 1.0+2.0**-11), # rounds to 1.0 (nearest even mode)
711n/a ('>e', b'\x3c\x00', 1.0+2.0**-12), # rounds to 1.0
712n/a ('>e', b'\x7b\xff', 65504), # largest normal
713n/a ('>e', b'\x7b\xff', 65519), # rounds to 65504
714n/a ('>e', b'\x80\x01', -2.0**-25 - 2.0**-35), # Rounds to minimum subnormal
715n/a ('>e', b'\x80\x00', -2.0**-25), # Underflows to zero (nearest even mode)
716n/a ('>e', b'\x80\x00', -2.0**-26), # Underflows to zero
717n/a ('>e', b'\xbc\x01', -1.0-2.0**-11 - 2.0**-16), # rounds to 1.0+2**(-10)
718n/a ('>e', b'\xbc\x00', -1.0-2.0**-11), # rounds to 1.0 (nearest even mode)
719n/a ('>e', b'\xbc\x00', -1.0-2.0**-12), # rounds to 1.0
720n/a ('>e', b'\xfb\xff', -65519), # rounds to 65504
721n/a ]
722n/a
723n/a for formatcode, bits, f in format_bits_float__rounding_list:
724n/a self.assertEqual(bits, struct.pack(formatcode, f))
725n/a
726n/a # This overflows, and so raises an error
727n/a format_bits_float__roundingError_list = [
728n/a # Values that round to infinity.
729n/a ('>e', 65520.0),
730n/a ('>e', 65536.0),
731n/a ('>e', 1e300),
732n/a ('>e', -65520.0),
733n/a ('>e', -65536.0),
734n/a ('>e', -1e300),
735n/a ('<e', 65520.0),
736n/a ('<e', 65536.0),
737n/a ('<e', 1e300),
738n/a ('<e', -65520.0),
739n/a ('<e', -65536.0),
740n/a ('<e', -1e300),
741n/a ]
742n/a
743n/a for formatcode, f in format_bits_float__roundingError_list:
744n/a self.assertRaises(OverflowError, struct.pack, formatcode, f)
745n/a
746n/a # Double rounding
747n/a format_bits_float__doubleRoundingError_list = [
748n/a ('>e', b'\x67\xff', 0x1ffdffffff * 2**-26), # should be 2047, if double-rounded 64>32>16, becomes 2048
749n/a ]
750n/a
751n/a for formatcode, bits, f in format_bits_float__doubleRoundingError_list:
752n/a self.assertEqual(bits, struct.pack(formatcode, f))
753n/a
754n/a
755n/aif __name__ == '__main__':
756n/a unittest.main()