]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_struct.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / test_struct.py
1 import os
2 import array
3 import unittest
4 import struct
5 import inspect
6 from test.test_support import run_unittest, check_warnings, check_py3k_warnings
7
8 import sys
9 ISBIGENDIAN = sys.byteorder == "big"
10 IS32BIT = sys.maxsize == 0x7fffffff
11
12 integer_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q'
13
14 testmod_filename = os.path.splitext(__file__)[0] + '.py'
15 # Native 'q' packing isn't available on systems that don't have the C
16 # long long type.
17 try:
18 struct.pack('q', 5)
19 except struct.error:
20 HAVE_LONG_LONG = False
21 else:
22 HAVE_LONG_LONG = True
23
24 def string_reverse(s):
25 return "".join(reversed(s))
26
27 def bigendian_to_native(value):
28 if ISBIGENDIAN:
29 return value
30 else:
31 return string_reverse(value)
32
33 class StructTest(unittest.TestCase):
34
35 def check_float_coerce(self, format, number):
36 # SF bug 1530559. struct.pack raises TypeError where it used
37 # to convert.
38 with check_warnings((".*integer argument expected, got float",
39 DeprecationWarning)) as w:
40 got = struct.pack(format, number)
41 lineno = inspect.currentframe().f_lineno - 1
42 self.assertEqual(w.filename, testmod_filename)
43 self.assertEqual(w.lineno, lineno)
44 self.assertEqual(len(w.warnings), 1)
45 expected = struct.pack(format, int(number))
46 self.assertEqual(got, expected)
47
48 def test_isbigendian(self):
49 self.assertEqual((struct.pack('=i', 1)[0] == chr(0)), ISBIGENDIAN)
50
51 def test_consistence(self):
52 self.assertRaises(struct.error, struct.calcsize, 'Z')
53
54 sz = struct.calcsize('i')
55 self.assertEqual(sz * 3, struct.calcsize('iii'))
56
57 fmt = 'cbxxxxxxhhhhiillffd?'
58 fmt3 = '3c3b18x12h6i6l6f3d3?'
59 sz = struct.calcsize(fmt)
60 sz3 = struct.calcsize(fmt3)
61 self.assertEqual(sz * 3, sz3)
62
63 self.assertRaises(struct.error, struct.pack, 'iii', 3)
64 self.assertRaises(struct.error, struct.pack, 'i', 3, 3, 3)
65 self.assertRaises((TypeError, struct.error), struct.pack, 'i', 'foo')
66 self.assertRaises((TypeError, struct.error), struct.pack, 'P', 'foo')
67 self.assertRaises(struct.error, struct.unpack, 'd', 'flap')
68 s = struct.pack('ii', 1, 2)
69 self.assertRaises(struct.error, struct.unpack, 'iii', s)
70 self.assertRaises(struct.error, struct.unpack, 'i', s)
71
72 def test_transitiveness(self):
73 c = 'a'
74 b = 1
75 h = 255
76 i = 65535
77 l = 65536
78 f = 3.1415
79 d = 3.1415
80 t = True
81
82 for prefix in ('', '@', '<', '>', '=', '!'):
83 for format in ('xcbhilfd?', 'xcBHILfd?'):
84 format = prefix + format
85 s = struct.pack(format, c, b, h, i, l, f, d, t)
86 cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s)
87 self.assertEqual(cp, c)
88 self.assertEqual(bp, b)
89 self.assertEqual(hp, h)
90 self.assertEqual(ip, i)
91 self.assertEqual(lp, l)
92 self.assertEqual(int(100 * fp), int(100 * f))
93 self.assertEqual(int(100 * dp), int(100 * d))
94 self.assertEqual(tp, t)
95
96 def test_new_features(self):
97 # Test some of the new features in detail
98 # (format, argument, big-endian result, little-endian result, asymmetric)
99 tests = [
100 ('c', 'a', 'a', 'a', 0),
101 ('xc', 'a', '\0a', '\0a', 0),
102 ('cx', 'a', 'a\0', 'a\0', 0),
103 ('s', 'a', 'a', 'a', 0),
104 ('0s', 'helloworld', '', '', 1),
105 ('1s', 'helloworld', 'h', 'h', 1),
106 ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
107 ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
108 ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
109 ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
110 ('b', 7, '\7', '\7', 0),
111 ('b', -7, '\371', '\371', 0),
112 ('B', 7, '\7', '\7', 0),
113 ('B', 249, '\371', '\371', 0),
114 ('h', 700, '\002\274', '\274\002', 0),
115 ('h', -700, '\375D', 'D\375', 0),
116 ('H', 700, '\002\274', '\274\002', 0),
117 ('H', 0x10000-700, '\375D', 'D\375', 0),
118 ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
119 ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
120 ('I', 70000000L, '\004,\035\200', '\200\035,\004', 0),
121 ('I', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
122 ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
123 ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
124 ('L', 70000000L, '\004,\035\200', '\200\035,\004', 0),
125 ('L', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
126 ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
127 ('d', 2.0, '@\000\000\000\000\000\000\000',
128 '\000\000\000\000\000\000\000@', 0),
129 ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
130 ('d', -2.0, '\300\000\000\000\000\000\000\000',
131 '\000\000\000\000\000\000\000\300', 0),
132 ('?', 0, '\0', '\0', 0),
133 ('?', 3, '\1', '\1', 1),
134 ('?', True, '\1', '\1', 0),
135 ('?', [], '\0', '\0', 1),
136 ('?', (1,), '\1', '\1', 1),
137 ]
138
139 for fmt, arg, big, lil, asy in tests:
140 for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
141 ('='+fmt, ISBIGENDIAN and big or lil)]:
142 res = struct.pack(xfmt, arg)
143 self.assertEqual(res, exp)
144 self.assertEqual(struct.calcsize(xfmt), len(res))
145 rev = struct.unpack(xfmt, res)[0]
146 if rev != arg:
147 self.assertTrue(asy)
148
149 def test_calcsize(self):
150 expected_size = {
151 'b': 1, 'B': 1,
152 'h': 2, 'H': 2,
153 'i': 4, 'I': 4,
154 'l': 4, 'L': 4,
155 'q': 8, 'Q': 8,
156 }
157
158 # standard integer sizes
159 for code in integer_codes:
160 for byteorder in ('=', '<', '>', '!'):
161 format = byteorder+code
162 size = struct.calcsize(format)
163 self.assertEqual(size, expected_size[code])
164
165 # native integer sizes, except 'q' and 'Q'
166 for format_pair in ('bB', 'hH', 'iI', 'lL'):
167 for byteorder in ['', '@']:
168 signed_size = struct.calcsize(byteorder + format_pair[0])
169 unsigned_size = struct.calcsize(byteorder + format_pair[1])
170 self.assertEqual(signed_size, unsigned_size)
171
172 # bounds for native integer sizes
173 self.assertEqual(struct.calcsize('b'), 1)
174 self.assertLessEqual(2, struct.calcsize('h'))
175 self.assertLessEqual(4, struct.calcsize('l'))
176 self.assertLessEqual(struct.calcsize('h'), struct.calcsize('i'))
177 self.assertLessEqual(struct.calcsize('i'), struct.calcsize('l'))
178
179 # tests for native 'q' and 'Q' when applicable
180 if HAVE_LONG_LONG:
181 self.assertEqual(struct.calcsize('q'), struct.calcsize('Q'))
182 self.assertLessEqual(8, struct.calcsize('q'))
183 self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))
184
185 def test_integers(self):
186 # Integer tests (bBhHiIlLqQ).
187 import binascii
188
189 class IntTester(unittest.TestCase):
190 def __init__(self, format):
191 super(IntTester, self).__init__(methodName='test_one')
192 self.format = format
193 self.code = format[-1]
194 self.direction = format[:-1]
195 if not self.direction in ('', '@', '=', '<', '>', '!'):
196 raise ValueError("unrecognized packing direction: %s" %
197 self.direction)
198 self.bytesize = struct.calcsize(format)
199 self.bitsize = self.bytesize * 8
200 if self.code in tuple('bhilq'):
201 self.signed = True
202 self.min_value = -(2L**(self.bitsize-1))
203 self.max_value = 2L**(self.bitsize-1) - 1
204 elif self.code in tuple('BHILQ'):
205 self.signed = False
206 self.min_value = 0
207 self.max_value = 2L**self.bitsize - 1
208 else:
209 raise ValueError("unrecognized format code: %s" %
210 self.code)
211
212 def test_one(self, x, pack=struct.pack,
213 unpack=struct.unpack,
214 unhexlify=binascii.unhexlify):
215
216 format = self.format
217 if self.min_value <= x <= self.max_value:
218 expected = long(x)
219 if self.signed and x < 0:
220 expected += 1L << self.bitsize
221 self.assertGreaterEqual(expected, 0)
222 expected = '%x' % expected
223 if len(expected) & 1:
224 expected = "0" + expected
225 expected = unhexlify(expected)
226 expected = ("\x00" * (self.bytesize - len(expected)) +
227 expected)
228 if (self.direction == '<' or
229 self.direction in ('', '@', '=') and not ISBIGENDIAN):
230 expected = string_reverse(expected)
231 self.assertEqual(len(expected), self.bytesize)
232
233 # Pack work?
234 got = pack(format, x)
235 self.assertEqual(got, expected)
236
237 # Unpack work?
238 retrieved = unpack(format, got)[0]
239 self.assertEqual(x, retrieved)
240
241 # Adding any byte should cause a "too big" error.
242 self.assertRaises((struct.error, TypeError), unpack, format,
243 '\x01' + got)
244 else:
245 # x is out of range -- verify pack realizes that.
246 self.assertRaises((OverflowError, ValueError, struct.error),
247 pack, format, x)
248
249 def run(self):
250 from random import randrange
251
252 # Create all interesting powers of 2.
253 values = []
254 for exp in range(self.bitsize + 3):
255 values.append(1L << exp)
256
257 # Add some random values.
258 for i in range(self.bitsize):
259 val = 0L
260 for j in range(self.bytesize):
261 val = (val << 8) | randrange(256)
262 values.append(val)
263
264 # Values absorbed from other tests
265 values.extend([300, 700000, sys.maxint*4])
266
267 # Try all those, and their negations, and +-1 from
268 # them. Note that this tests all power-of-2
269 # boundaries in range, and a few out of range, plus
270 # +-(2**n +- 1).
271 for base in values:
272 for val in -base, base:
273 for incr in -1, 0, 1:
274 x = val + incr
275 self.test_one(int(x))
276 self.test_one(long(x))
277
278 # Some error cases.
279 class NotAnIntNS(object):
280 def __int__(self):
281 return 42
282
283 def __long__(self):
284 return 1729L
285
286 class NotAnIntOS:
287 def __int__(self):
288 return 85
289
290 def __long__(self):
291 return -163L
292
293 # Objects with an '__index__' method should be allowed
294 # to pack as integers. That is assuming the implemented
295 # '__index__' method returns and 'int' or 'long'.
296 class Indexable(object):
297 def __init__(self, value):
298 self._value = value
299
300 def __index__(self):
301 return self._value
302
303 # If the '__index__' method raises a type error, then
304 # '__int__' should be used with a deprecation warning.
305 class BadIndex(object):
306 def __index__(self):
307 raise TypeError
308
309 def __int__(self):
310 return 42
311
312 self.assertRaises((TypeError, struct.error),
313 struct.pack, self.format,
314 "a string")
315 self.assertRaises((TypeError, struct.error),
316 struct.pack, self.format,
317 randrange)
318 with check_warnings(("integer argument expected, "
319 "got non-integer", DeprecationWarning)):
320 with self.assertRaises((TypeError, struct.error)):
321 struct.pack(self.format, 3+42j)
322
323 # an attempt to convert a non-integer (with an
324 # implicit conversion via __int__) should succeed,
325 # with a DeprecationWarning
326 for nonint in NotAnIntNS(), NotAnIntOS(), BadIndex():
327 with check_warnings((".*integer argument expected, got non"
328 "-integer", DeprecationWarning)) as w:
329 got = struct.pack(self.format, nonint)
330 lineno = inspect.currentframe().f_lineno - 1
331 self.assertEqual(w.filename, testmod_filename)
332 self.assertEqual(w.lineno, lineno)
333 self.assertEqual(len(w.warnings), 1)
334 expected = struct.pack(self.format, int(nonint))
335 self.assertEqual(got, expected)
336
337 # Check for legitimate values from '__index__'.
338 for obj in (Indexable(0), Indexable(10), Indexable(17),
339 Indexable(42), Indexable(100), Indexable(127)):
340 try:
341 struct.pack(format, obj)
342 except:
343 self.fail("integer code pack failed on object "
344 "with '__index__' method")
345
346 # Check for bogus values from '__index__'.
347 for obj in (Indexable('a'), Indexable(u'b'), Indexable(None),
348 Indexable({'a': 1}), Indexable([1, 2, 3])):
349 self.assertRaises((TypeError, struct.error),
350 struct.pack, self.format,
351 obj)
352
353 byteorders = '', '@', '=', '<', '>', '!'
354 for code in integer_codes:
355 for byteorder in byteorders:
356 if (byteorder in ('', '@') and code in ('q', 'Q') and
357 not HAVE_LONG_LONG):
358 continue
359 format = byteorder+code
360 t = IntTester(format)
361 t.run()
362
363 def test_p_code(self):
364 # Test p ("Pascal string") code.
365 for code, input, expected, expectedback in [
366 ('p','abc', '\x00', ''),
367 ('1p', 'abc', '\x00', ''),
368 ('2p', 'abc', '\x01a', 'a'),
369 ('3p', 'abc', '\x02ab', 'ab'),
370 ('4p', 'abc', '\x03abc', 'abc'),
371 ('5p', 'abc', '\x03abc\x00', 'abc'),
372 ('6p', 'abc', '\x03abc\x00\x00', 'abc'),
373 ('1000p', 'x'*1000, '\xff' + 'x'*999, 'x'*255)]:
374 got = struct.pack(code, input)
375 self.assertEqual(got, expected)
376 (got,) = struct.unpack(code, got)
377 self.assertEqual(got, expectedback)
378
379 def test_705836(self):
380 # SF bug 705836. "<f" and ">f" had a severe rounding bug, where a carry
381 # from the low-order discarded bits could propagate into the exponent
382 # field, causing the result to be wrong by a factor of 2.
383 import math
384
385 for base in range(1, 33):
386 # smaller <- largest representable float less than base.
387 delta = 0.5
388 while base - delta / 2.0 != base:
389 delta /= 2.0
390 smaller = base - delta
391 # Packing this rounds away a solid string of trailing 1 bits.
392 packed = struct.pack("<f", smaller)
393 unpacked = struct.unpack("<f", packed)[0]
394 # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
395 # 16, respectively.
396 self.assertEqual(base, unpacked)
397 bigpacked = struct.pack(">f", smaller)
398 self.assertEqual(bigpacked, string_reverse(packed))
399 unpacked = struct.unpack(">f", bigpacked)[0]
400 self.assertEqual(base, unpacked)
401
402 # Largest finite IEEE single.
403 big = (1 << 24) - 1
404 big = math.ldexp(big, 127 - 23)
405 packed = struct.pack(">f", big)
406 unpacked = struct.unpack(">f", packed)[0]
407 self.assertEqual(big, unpacked)
408
409 # The same, but tack on a 1 bit so it rounds up to infinity.
410 big = (1 << 25) - 1
411 big = math.ldexp(big, 127 - 24)
412 self.assertRaises(OverflowError, struct.pack, ">f", big)
413
414 def test_1530559(self):
415 # SF bug 1530559. struct.pack raises TypeError where it used to convert.
416 for endian in ('', '>', '<'):
417 for fmt in integer_codes:
418 self.check_float_coerce(endian + fmt, 1.0)
419 self.check_float_coerce(endian + fmt, 1.5)
420
421 def test_unpack_from(self, cls=str):
422 data = cls('abcd01234')
423 fmt = '4s'
424 s = struct.Struct(fmt)
425
426 self.assertEqual(s.unpack_from(data), ('abcd',))
427 self.assertEqual(struct.unpack_from(fmt, data), ('abcd',))
428 for i in xrange(6):
429 self.assertEqual(s.unpack_from(data, i), (data[i:i+4],))
430 self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],))
431 for i in xrange(6, len(data) + 1):
432 self.assertRaises(struct.error, s.unpack_from, data, i)
433 self.assertRaises(struct.error, struct.unpack_from, fmt, data, i)
434
435 def test_pack_into(self):
436 test_string = 'Reykjavik rocks, eow!'
437 writable_buf = array.array('c', ' '*100)
438 fmt = '21s'
439 s = struct.Struct(fmt)
440
441 # Test without offset
442 s.pack_into(writable_buf, 0, test_string)
443 from_buf = writable_buf.tostring()[:len(test_string)]
444 self.assertEqual(from_buf, test_string)
445
446 # Test with offset.
447 s.pack_into(writable_buf, 10, test_string)
448 from_buf = writable_buf.tostring()[:len(test_string)+10]
449 self.assertEqual(from_buf, test_string[:10] + test_string)
450
451 # Go beyond boundaries.
452 small_buf = array.array('c', ' '*10)
453 self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 0,
454 test_string)
455 self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 2,
456 test_string)
457
458 # Test bogus offset (issue 3694)
459 sb = small_buf
460 self.assertRaises((TypeError, struct.error), struct.pack_into, b'', sb,
461 None)
462
463 def test_pack_into_fn(self):
464 test_string = 'Reykjavik rocks, eow!'
465 writable_buf = array.array('c', ' '*100)
466 fmt = '21s'
467 pack_into = lambda *args: struct.pack_into(fmt, *args)
468
469 # Test without offset.
470 pack_into(writable_buf, 0, test_string)
471 from_buf = writable_buf.tostring()[:len(test_string)]
472 self.assertEqual(from_buf, test_string)
473
474 # Test with offset.
475 pack_into(writable_buf, 10, test_string)
476 from_buf = writable_buf.tostring()[:len(test_string)+10]
477 self.assertEqual(from_buf, test_string[:10] + test_string)
478
479 # Go beyond boundaries.
480 small_buf = array.array('c', ' '*10)
481 self.assertRaises((ValueError, struct.error), pack_into, small_buf, 0,
482 test_string)
483 self.assertRaises((ValueError, struct.error), pack_into, small_buf, 2,
484 test_string)
485
486 def test_unpack_with_buffer(self):
487 with check_py3k_warnings(("buffer.. not supported in 3.x",
488 DeprecationWarning)):
489 # SF bug 1563759: struct.unpack doesn't support buffer protocol objects
490 data1 = array.array('B', '\x12\x34\x56\x78')
491 data2 = buffer('......\x12\x34\x56\x78......', 6, 4)
492 for data in [data1, data2]:
493 value, = struct.unpack('>I', data)
494 self.assertEqual(value, 0x12345678)
495
496 self.test_unpack_from(cls=buffer)
497
498 def test_bool(self):
499 class ExplodingBool(object):
500 def __nonzero__(self):
501 raise IOError
502 for prefix in tuple("<>!=")+('',):
503 false = (), [], [], '', 0
504 true = [1], 'test', 5, -1, 0xffffffffL+1, 0xffffffff//2
505
506 falseFormat = prefix + '?' * len(false)
507 packedFalse = struct.pack(falseFormat, *false)
508 unpackedFalse = struct.unpack(falseFormat, packedFalse)
509
510 trueFormat = prefix + '?' * len(true)
511 packedTrue = struct.pack(trueFormat, *true)
512 unpackedTrue = struct.unpack(trueFormat, packedTrue)
513
514 self.assertEqual(len(true), len(unpackedTrue))
515 self.assertEqual(len(false), len(unpackedFalse))
516
517 for t in unpackedFalse:
518 self.assertFalse(t)
519 for t in unpackedTrue:
520 self.assertTrue(t)
521
522 packed = struct.pack(prefix+'?', 1)
523
524 self.assertEqual(len(packed), struct.calcsize(prefix+'?'))
525
526 if len(packed) != 1:
527 self.assertFalse(prefix, msg='encoded bool is not one byte: %r'
528 %packed)
529
530 self.assertRaises(IOError, struct.pack, prefix + '?',
531 ExplodingBool())
532
533 for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
534 self.assertTrue(struct.unpack('>?', c)[0])
535
536 @unittest.skipUnless(IS32BIT, "Specific to 32bit machines")
537 def test_crasher(self):
538 self.assertRaises(MemoryError, struct.pack, "357913941c", "a")
539
540 def test_count_overflow(self):
541 hugecount = '{}b'.format(sys.maxsize+1)
542 self.assertRaises(struct.error, struct.calcsize, hugecount)
543
544 hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2)
545 self.assertRaises(struct.error, struct.calcsize, hugecount2)
546
547 def test_main():
548 run_unittest(StructTest)
549
550 if __name__ == '__main__':
551 test_main()