Changeset 391 for python/trunk/Lib/test/test_struct.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/test/test_struct.py
r2 r391 1 import os 1 2 import array 2 3 import unittest 3 4 import struct 4 import warnings 5 warnings.filterwarnings("ignore", "struct integer overflow masking is deprecated", 6 DeprecationWarning) 7 8 from functools import wraps 9 from test.test_support import TestFailed, verbose, run_unittest 5 import inspect 6 from test import test_support as support 7 from test.test_support import (check_warnings, check_py3k_warnings) 10 8 11 9 import sys 12 10 ISBIGENDIAN = sys.byteorder == "big" 13 11 IS32BIT = sys.maxsize == 0x7fffffff 14 del sys 15 12 13 integer_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q' 14 15 testmod_filename = os.path.splitext(__file__)[0] + '.py' 16 # Native 'q' packing isn't available on systems that don't have the C 17 # long long type. 16 18 try: 17 import _struct 18 except ImportError: 19 PY_STRUCT_RANGE_CHECKING = 0 20 PY_STRUCT_OVERFLOW_MASKING = 1 21 PY_STRUCT_FLOAT_COERCE = 2 19 struct.pack('q', 5) 20 except struct.error: 21 HAVE_LONG_LONG = False 22 22 else: 23 PY_STRUCT_RANGE_CHECKING = getattr(_struct, '_PY_STRUCT_RANGE_CHECKING', 0) 24 PY_STRUCT_OVERFLOW_MASKING = getattr(_struct, '_PY_STRUCT_OVERFLOW_MASKING', 0) 25 PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0) 23 HAVE_LONG_LONG = True 26 24 27 25 def string_reverse(s): … … 34 32 return string_reverse(value) 35 33 36 def with_warning_restore(func):37 @wraps(func)38 def decorator(*args, **kw):39 with warnings.catch_warnings():40 # We need this function to warn every time, so stick an41 # unqualifed 'always' at the head of the filter list42 warnings.simplefilter("always")43 warnings.filterwarnings("error", category=DeprecationWarning)44 return func(*args, **kw)45 return decorator46 47 @with_warning_restore48 def deprecated_err(func, *args):49 try:50 func(*args)51 except (struct.error, TypeError):52 pass53 except DeprecationWarning:54 if not PY_STRUCT_OVERFLOW_MASKING:55 raise TestFailed, "%s%s expected to raise DeprecationWarning" % (56 func.__name__, args)57 else:58 raise TestFailed, "%s%s did not raise error" % (59 func.__name__, args)60 61 62 34 class StructTest(unittest.TestCase): 63 35 64 @with_warning_restore65 36 def check_float_coerce(self, format, number): 66 # SF bug 1530559. struct.pack raises TypeError where it used to convert. 67 if PY_STRUCT_FLOAT_COERCE == 2: 68 # Test for pre-2.5 struct module 69 packed = struct.pack(format, number) 70 floored = struct.unpack(format, packed)[0] 71 self.assertEqual(floored, int(number), 72 "did not correcly coerce float to int") 73 return 74 try: 75 struct.pack(format, number) 76 except (struct.error, TypeError): 77 if PY_STRUCT_FLOAT_COERCE: 78 self.fail("expected DeprecationWarning for float coerce") 79 except DeprecationWarning: 80 if not PY_STRUCT_FLOAT_COERCE: 81 self.fail("expected to raise struct.error for float coerce") 82 else: 83 self.fail("did not raise error for float coerce") 37 # SF bug 1530559. struct.pack raises TypeError where it used 38 # to convert. 39 with check_warnings((".*integer argument expected, got float", 40 DeprecationWarning)) as w: 41 got = struct.pack(format, number) 42 lineno = inspect.currentframe().f_lineno - 1 43 self.assertEqual(w.filename, testmod_filename) 44 self.assertEqual(w.lineno, lineno) 45 self.assertEqual(len(w.warnings), 1) 46 expected = struct.pack(format, int(number)) 47 self.assertEqual(got, expected) 84 48 85 49 def test_isbigendian(self): … … 100 64 self.assertRaises(struct.error, struct.pack, 'iii', 3) 101 65 self.assertRaises(struct.error, struct.pack, 'i', 3, 3, 3) 102 self.assertRaises( struct.error, struct.pack, 'i', 'foo')103 self.assertRaises( struct.error, struct.pack, 'P', 'foo')66 self.assertRaises((TypeError, struct.error), struct.pack, 'i', 'foo') 67 self.assertRaises((TypeError, struct.error), struct.pack, 'P', 'foo') 104 68 self.assertRaises(struct.error, struct.unpack, 'd', 'flap') 105 69 s = struct.pack('ii', 1, 2) … … 182 146 rev = struct.unpack(xfmt, res)[0] 183 147 if rev != arg: 184 self.assert_(asy) 185 186 def test_native_qQ(self): 187 # can't pack -1 as unsigned regardless 188 self.assertRaises((struct.error, TypeError), struct.pack, "Q", -1) 189 # can't pack string as 'q' regardless 190 self.assertRaises(struct.error, struct.pack, "q", "a") 191 # ditto, but 'Q' 192 self.assertRaises(struct.error, struct.pack, "Q", "a") 193 194 try: 195 struct.pack("q", 5) 196 except struct.error: 197 # does not have native q/Q 198 pass 199 else: 200 bytes = struct.calcsize('q') 201 # The expected values here are in big-endian format, primarily 202 # because I'm on a little-endian machine and so this is the 203 # clearest way (for me) to force the code to get exercised. 204 for format, input, expected in ( 205 ('q', -1, '\xff' * bytes), 206 ('q', 0, '\x00' * bytes), 207 ('Q', 0, '\x00' * bytes), 208 ('q', 1L, '\x00' * (bytes-1) + '\x01'), 209 ('Q', (1L << (8*bytes))-1, '\xff' * bytes), 210 ('q', (1L << (8*bytes-1))-1, '\x7f' + '\xff' * (bytes - 1))): 211 got = struct.pack(format, input) 212 native_expected = bigendian_to_native(expected) 213 self.assertEqual(got, native_expected) 214 retrieved = struct.unpack(format, got)[0] 215 self.assertEqual(retrieved, input) 216 217 def test_standard_integers(self): 218 # Standard integer tests (bBhHiIlLqQ). 148 self.assertTrue(asy) 149 150 def test_calcsize(self): 151 expected_size = { 152 'b': 1, 'B': 1, 153 'h': 2, 'H': 2, 154 'i': 4, 'I': 4, 155 'l': 4, 'L': 4, 156 'q': 8, 'Q': 8, 157 } 158 159 # standard integer sizes 160 for code in integer_codes: 161 for byteorder in ('=', '<', '>', '!'): 162 format = byteorder+code 163 size = struct.calcsize(format) 164 self.assertEqual(size, expected_size[code]) 165 166 # native integer sizes, except 'q' and 'Q' 167 for format_pair in ('bB', 'hH', 'iI', 'lL'): 168 for byteorder in ['', '@']: 169 signed_size = struct.calcsize(byteorder + format_pair[0]) 170 unsigned_size = struct.calcsize(byteorder + format_pair[1]) 171 self.assertEqual(signed_size, unsigned_size) 172 173 # bounds for native integer sizes 174 self.assertEqual(struct.calcsize('b'), 1) 175 self.assertLessEqual(2, struct.calcsize('h')) 176 self.assertLessEqual(4, struct.calcsize('l')) 177 self.assertLessEqual(struct.calcsize('h'), struct.calcsize('i')) 178 self.assertLessEqual(struct.calcsize('i'), struct.calcsize('l')) 179 180 # tests for native 'q' and 'Q' when applicable 181 if HAVE_LONG_LONG: 182 self.assertEqual(struct.calcsize('q'), struct.calcsize('Q')) 183 self.assertLessEqual(8, struct.calcsize('q')) 184 self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q')) 185 186 def test_integers(self): 187 # Integer tests (bBhHiIlLqQ). 219 188 import binascii 220 189 221 190 class IntTester(unittest.TestCase): 222 223 # XXX Most std integer modes fail to test for out-of-range.224 # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but225 # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C226 # reported by Mark Favas).227 BUGGY_RANGE_CHECK = "bBhHiIlL"228 229 def __init__(self, formatpair, bytesize):230 self. assertEqual(len(formatpair), 2)231 self. formatpair = formatpair232 for direction in "<>!=":233 for code in formatpair:234 format = direction + code235 self.assertEqual(struct.calcsize(format), bytesize)236 self.bytesize = bytesize237 self.bitsize = bytesize * 8238 self.signed_code, self.unsigned_code = formatpair239 self.unsigned_min = 0240 self.unsigned_max = 2L**self.bitsize - 1241 self.signed_min = -(2L**(self.bitsize-1))242 self.signed_max = 2L**(self.bitsize-1) - 1191 def __init__(self, format): 192 super(IntTester, self).__init__(methodName='test_one') 193 self.format = format 194 self.code = format[-1] 195 self.direction = format[:-1] 196 if not self.direction in ('', '@', '=', '<', '>', '!'): 197 raise ValueError("unrecognized packing direction: %s" % 198 self.direction) 199 self.bytesize = struct.calcsize(format) 200 self.bitsize = self.bytesize * 8 201 if self.code in tuple('bhilq'): 202 self.signed = True 203 self.min_value = -(2L**(self.bitsize-1)) 204 self.max_value = 2L**(self.bitsize-1) - 1 205 elif self.code in tuple('BHILQ'): 206 self.signed = False 207 self.min_value = 0 208 self.max_value = 2L**self.bitsize - 1 209 else: 210 raise ValueError("unrecognized format code: %s" % 211 self.code) 243 212 244 213 def test_one(self, x, pack=struct.pack, 245 214 unpack=struct.unpack, 246 215 unhexlify=binascii.unhexlify): 247 # Try signed. 248 code = self.signed_code 249 if self.signed_min <= x <= self.signed_max: 250 # Try big-endian. 216 217 format = self.format 218 if self.min_value <= x <= self.max_value: 251 219 expected = long(x) 252 if x < 0:220 if self.signed and x < 0: 253 221 expected += 1L << self.bitsize 254 self.assert_(expected >0)255 expected = hex(expected)[2:-1] # chop "0x" and trailing 'L'222 self.assertGreaterEqual(expected, 0) 223 expected = '%x' % expected 256 224 if len(expected) & 1: 257 225 expected = "0" + expected 258 226 expected = unhexlify(expected) 259 expected = "\x00" * (self.bytesize - len(expected)) + expected 227 expected = ("\x00" * (self.bytesize - len(expected)) + 228 expected) 229 if (self.direction == '<' or 230 self.direction in ('', '@', '=') and not ISBIGENDIAN): 231 expected = string_reverse(expected) 232 self.assertEqual(len(expected), self.bytesize) 260 233 261 234 # Pack work? 262 format = ">" + code263 235 got = pack(format, x) 264 236 self.assertEqual(got, expected) … … 271 243 self.assertRaises((struct.error, TypeError), unpack, format, 272 244 '\x01' + got) 273 # Try little-endian.274 format = "<" + code275 expected = string_reverse(expected)276 277 # Pack work?278 got = pack(format, x)279 self.assertEqual(got, expected)280 281 # Unpack work?282 retrieved = unpack(format, got)[0]283 self.assertEqual(x, retrieved)284 285 # Adding any byte should cause a "too big" error.286 self.assertRaises((struct.error, TypeError), unpack, format,287 '\x01' + got)288 289 245 else: 290 246 # x is out of range -- verify pack realizes that. 291 if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK: 292 if verbose: 293 print "Skipping buggy range check for code", code 294 else: 295 deprecated_err(pack, ">" + code, x) 296 deprecated_err(pack, "<" + code, x) 297 298 # Much the same for unsigned. 299 code = self.unsigned_code 300 if self.unsigned_min <= x <= self.unsigned_max: 301 # Try big-endian. 302 format = ">" + code 303 expected = long(x) 304 expected = hex(expected)[2:-1] # chop "0x" and trailing 'L' 305 if len(expected) & 1: 306 expected = "0" + expected 307 expected = unhexlify(expected) 308 expected = "\x00" * (self.bytesize - len(expected)) + expected 309 310 # Pack work? 311 got = pack(format, x) 312 self.assertEqual(got, expected) 313 314 # Unpack work? 315 retrieved = unpack(format, got)[0] 316 self.assertEqual(x, retrieved) 317 318 # Adding any byte should cause a "too big" error. 319 self.assertRaises((struct.error, TypeError), unpack, format, 320 '\x01' + got) 321 322 # Try little-endian. 323 format = "<" + code 324 expected = string_reverse(expected) 325 326 # Pack work? 327 got = pack(format, x) 328 self.assertEqual(got, expected) 329 330 # Unpack work? 331 retrieved = unpack(format, got)[0] 332 self.assertEqual(x, retrieved) 333 334 # Adding any byte should cause a "too big" error. 335 self.assertRaises((struct.error, TypeError), unpack, format, 336 '\x01' + got) 337 338 else: 339 # x is out of range -- verify pack realizes that. 340 if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK: 341 if verbose: 342 print "Skipping buggy range check for code", code 343 else: 344 deprecated_err(pack, ">" + code, x) 345 deprecated_err(pack, "<" + code, x) 247 self.assertRaises((OverflowError, ValueError, struct.error), 248 pack, format, x) 346 249 347 250 def run(self): … … 360 263 values.append(val) 361 264 362 # Try all those, and their negations, and +-1 from them. Note 363 # that this tests all power-of-2 boundaries in range, and a few out 364 # of range, plus +-(2**n +- 1). 265 # Values absorbed from other tests 266 values.extend([300, 700000, sys.maxint*4]) 267 268 # Try all those, and their negations, and +-1 from 269 # them. Note that this tests all power-of-2 270 # boundaries in range, and a few out of range, plus 271 # +-(2**n +- 1). 365 272 for base in values: 366 273 for val in -base, base: 367 274 for incr in -1, 0, 1: 368 275 x = val + incr 369 try: 370 x = int(x) 371 except OverflowError: 372 pass 373 self.test_one(x) 276 self.test_one(int(x)) 277 self.test_one(long(x)) 374 278 375 279 # Some error cases. 376 for direction in "<>": 377 for code in self.formatpair: 378 for badobject in "a string", 3+42j, randrange: 379 self.assertRaises((struct.error, TypeError), 380 struct.pack, direction + code, 381 badobject) 382 383 for args in [("bB", 1), 384 ("hH", 2), 385 ("iI", 4), 386 ("lL", 4), 387 ("qQ", 8)]: 388 t = IntTester(*args) 389 t.run() 280 class NotAnIntNS(object): 281 def __int__(self): 282 return 42 283 284 def __long__(self): 285 return 1729L 286 287 class NotAnIntOS: 288 def __int__(self): 289 return 85 290 291 def __long__(self): 292 return -163L 293 294 # Objects with an '__index__' method should be allowed 295 # to pack as integers. That is assuming the implemented 296 # '__index__' method returns and 'int' or 'long'. 297 class Indexable(object): 298 def __init__(self, value): 299 self._value = value 300 301 def __index__(self): 302 return self._value 303 304 # If the '__index__' method raises a type error, then 305 # '__int__' should be used with a deprecation warning. 306 class BadIndex(object): 307 def __index__(self): 308 raise TypeError 309 310 def __int__(self): 311 return 42 312 313 self.assertRaises((TypeError, struct.error), 314 struct.pack, self.format, 315 "a string") 316 self.assertRaises((TypeError, struct.error), 317 struct.pack, self.format, 318 randrange) 319 with check_warnings(("integer argument expected, " 320 "got non-integer", DeprecationWarning)): 321 with self.assertRaises((TypeError, struct.error)): 322 struct.pack(self.format, 3+42j) 323 324 # an attempt to convert a non-integer (with an 325 # implicit conversion via __int__) should succeed, 326 # with a DeprecationWarning 327 for nonint in NotAnIntNS(), NotAnIntOS(), BadIndex(): 328 with check_warnings((".*integer argument expected, got non" 329 "-integer", DeprecationWarning)) as w: 330 got = struct.pack(self.format, nonint) 331 lineno = inspect.currentframe().f_lineno - 1 332 self.assertEqual(w.filename, testmod_filename) 333 self.assertEqual(w.lineno, lineno) 334 self.assertEqual(len(w.warnings), 1) 335 expected = struct.pack(self.format, int(nonint)) 336 self.assertEqual(got, expected) 337 338 # Check for legitimate values from '__index__'. 339 for obj in (Indexable(0), Indexable(10), Indexable(17), 340 Indexable(42), Indexable(100), Indexable(127)): 341 try: 342 struct.pack(format, obj) 343 except: 344 self.fail("integer code pack failed on object " 345 "with '__index__' method") 346 347 # Check for bogus values from '__index__'. 348 for obj in (Indexable('a'), Indexable(u'b'), Indexable(None), 349 Indexable({'a': 1}), Indexable([1, 2, 3])): 350 self.assertRaises((TypeError, struct.error), 351 struct.pack, self.format, 352 obj) 353 354 byteorders = '', '@', '=', '<', '>', '!' 355 for code in integer_codes: 356 for byteorder in byteorders: 357 if (byteorder in ('', '@') and code in ('q', 'Q') and 358 not HAVE_LONG_LONG): 359 continue 360 format = byteorder+code 361 t = IntTester(format) 362 t.run() 390 363 391 364 def test_p_code(self): … … 440 413 self.assertRaises(OverflowError, struct.pack, ">f", big) 441 414 442 if PY_STRUCT_RANGE_CHECKING: 443 def test_1229380(self): 444 # SF bug 1229380. No struct.pack exception for some out of 445 # range integers 446 import sys 447 for endian in ('', '>', '<'): 448 for cls in (int, long): 449 for fmt in ('B', 'H', 'I', 'L'): 450 deprecated_err(struct.pack, endian + fmt, cls(-1)) 451 452 deprecated_err(struct.pack, endian + 'B', cls(300)) 453 deprecated_err(struct.pack, endian + 'H', cls(70000)) 454 455 deprecated_err(struct.pack, endian + 'I', sys.maxint * 4L) 456 deprecated_err(struct.pack, endian + 'L', sys.maxint * 4L) 457 458 def XXXtest_1530559(self): 459 # XXX This is broken: see the bug report 415 def test_1530559(self): 460 416 # SF bug 1530559. struct.pack raises TypeError where it used to convert. 461 417 for endian in ('', '>', '<'): 462 for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'):418 for fmt in integer_codes: 463 419 self.check_float_coerce(endian + fmt, 1.0) 464 420 self.check_float_coerce(endian + fmt, 1.5) 465 421 466 def test_issue4228(self): 467 # Packing a long may yield either 32 or 64 bits 468 x = struct.pack('L', -1)[:4] 469 self.assertEqual(x, '\xff'*4) 470 471 def test_unpack_from(self): 472 test_string = 'abcd01234' 422 def test_unpack_from(self, cls=str): 423 data = cls('abcd01234') 473 424 fmt = '4s' 474 425 s = struct.Struct(fmt) 475 for cls in (str, buffer): 476 data = cls(test_string) 477 self.assertEqual(s.unpack_from(data), ('abcd',)) 478 self.assertEqual(s.unpack_from(data, 2), ('cd01',)) 479 self.assertEqual(s.unpack_from(data, 4), ('0123',)) 480 for i in xrange(6): 481 self.assertEqual(s.unpack_from(data, i), (data[i:i+4],)) 482 for i in xrange(6, len(test_string) + 1): 483 self.assertRaises(struct.error, s.unpack_from, data, i) 484 for cls in (str, buffer): 485 data = cls(test_string) 486 self.assertEqual(struct.unpack_from(fmt, data), ('abcd',)) 487 self.assertEqual(struct.unpack_from(fmt, data, 2), ('cd01',)) 488 self.assertEqual(struct.unpack_from(fmt, data, 4), ('0123',)) 489 for i in xrange(6): 490 self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],)) 491 for i in xrange(6, len(test_string) + 1): 492 self.assertRaises(struct.error, struct.unpack_from, fmt, data, i) 426 427 self.assertEqual(s.unpack_from(data), ('abcd',)) 428 self.assertEqual(struct.unpack_from(fmt, data), ('abcd',)) 429 for i in xrange(6): 430 self.assertEqual(s.unpack_from(data, i), (data[i:i+4],)) 431 self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],)) 432 for i in xrange(6, len(data) + 1): 433 self.assertRaises(struct.error, s.unpack_from, data, i) 434 self.assertRaises(struct.error, struct.unpack_from, fmt, data, i) 493 435 494 436 def test_pack_into(self): … … 510 452 # Go beyond boundaries. 511 453 small_buf = array.array('c', ' '*10) 512 self.assertRaises(struct.error, s.pack_into, small_buf, 0, test_string) 513 self.assertRaises(struct.error, s.pack_into, small_buf, 2, test_string) 454 self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 0, 455 test_string) 456 self.assertRaises((ValueError, struct.error), s.pack_into, small_buf, 2, 457 test_string) 514 458 515 459 # Test bogus offset (issue 3694) 516 460 sb = small_buf 517 self.assertRaises(TypeError, struct.pack_into, b'1', sb, None) 461 self.assertRaises((TypeError, struct.error), struct.pack_into, b'', sb, 462 None) 518 463 519 464 def test_pack_into_fn(self): … … 535 480 # Go beyond boundaries. 536 481 small_buf = array.array('c', ' '*10) 537 self.assertRaises(struct.error, pack_into, small_buf, 0, test_string) 538 self.assertRaises(struct.error, pack_into, small_buf, 2, test_string) 482 self.assertRaises((ValueError, struct.error), pack_into, small_buf, 0, 483 test_string) 484 self.assertRaises((ValueError, struct.error), pack_into, small_buf, 2, 485 test_string) 539 486 540 487 def test_unpack_with_buffer(self): 541 # SF bug 1563759: struct.unpack doens't support buffer protocol objects 542 data1 = array.array('B', '\x12\x34\x56\x78') 543 data2 = buffer('......\x12\x34\x56\x78......', 6, 4) 544 for data in [data1, data2]: 488 with check_py3k_warnings(("buffer.. not supported in 3.x", 489 DeprecationWarning)): 490 # SF bug 1563759: struct.unpack doesn't support buffer protocol objects 491 data1 = array.array('B', '\x12\x34\x56\x78') 492 data2 = buffer('......\x12\x34\x56\x78......', 6, 4) 493 for data in [data1, data2]: 494 value, = struct.unpack('>I', data) 495 self.assertEqual(value, 0x12345678) 496 497 self.test_unpack_from(cls=buffer) 498 499 def test_unpack_with_memoryview(self): 500 # Bug 10212: struct.unpack doesn't support new buffer protocol objects 501 data1 = memoryview('\x12\x34\x56\x78') 502 for data in [data1,]: 545 503 value, = struct.unpack('>I', data) 546 504 self.assertEqual(value, 0x12345678) 505 self.test_unpack_from(cls=memoryview) 547 506 548 507 def test_bool(self): 508 class ExplodingBool(object): 509 def __nonzero__(self): 510 raise IOError 549 511 for prefix in tuple("<>!=")+('',): 550 512 false = (), [], [], '', 0 551 true = [1], 'test', 5, -1, 0xffffffffL+1, 0xffffffff/ 2513 true = [1], 'test', 5, -1, 0xffffffffL+1, 0xffffffff//2 552 514 553 515 falseFormat = prefix + '?' * len(false) … … 575 537 %packed) 576 538 577 for c in '\x01\x7f\xff\x0f\xf0': 578 self.assertTrue(struct.unpack('>?', c)[0]) 579 580 if IS32BIT: 581 def test_crasher(self): 582 self.assertRaises(MemoryError, struct.pack, "357913941c", "a") 583 584 539 self.assertRaises(IOError, struct.pack, prefix + '?', 540 ExplodingBool()) 541 542 for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: 543 self.assertTrue(struct.unpack('>?', c)[0]) 544 545 @unittest.skipUnless(IS32BIT, "Specific to 32bit machines") 546 def test_crasher(self): 547 self.assertRaises(MemoryError, struct.pack, "357913941c", "a") 548 549 def test_count_overflow(self): 550 hugecount = '{}b'.format(sys.maxsize+1) 551 self.assertRaises(struct.error, struct.calcsize, hugecount) 552 553 hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) 554 self.assertRaises(struct.error, struct.calcsize, hugecount2) 555 556 def check_sizeof(self, format_str, number_of_codes): 557 # The size of 'PyStructObject' 558 totalsize = support.calcobjsize('5P') 559 # The size taken up by the 'formatcode' dynamic array 560 totalsize += struct.calcsize('3P') * (number_of_codes + 1) 561 support.check_sizeof(self, struct.Struct(format_str), totalsize) 562 563 @support.cpython_only 564 def test__sizeof__(self): 565 for code in integer_codes: 566 self.check_sizeof(code, 1) 567 self.check_sizeof('BHILfdspP', 9) 568 self.check_sizeof('B' * 1234, 1234) 569 self.check_sizeof('fd', 2) 570 self.check_sizeof('xxxxxxxxxxxxxx', 0) 571 self.check_sizeof('100H', 100) 572 self.check_sizeof('187s', 1) 573 self.check_sizeof('20p', 1) 574 self.check_sizeof('0s', 1) 575 self.check_sizeof('0c', 0) 585 576 586 577 def test_main(): 587 run_unittest(StructTest)578 support.run_unittest(StructTest) 588 579 589 580 if __name__ == '__main__':
Note:
See TracChangeset
for help on using the changeset viewer.