blob: 7981a5245a7b576ca129e4852a65efe499ba8e70 [file] [log] [blame]
Barry Warsaw04f357c2002-07-23 19:04:11 +00001from test.test_support import TestFailed, verbose, verify
Thomas Wouters477c8d52006-05-27 19:21:47 +00002import test.test_support
Barry Warsaw07a0eec1996-12-12 23:34:06 +00003import struct
Thomas Wouters477c8d52006-05-27 19:21:47 +00004import array
5import unittest
Barry Warsaw07a0eec1996-12-12 23:34:06 +00006
Tim Peters17e17d42001-06-13 22:45:27 +00007import sys
8ISBIGENDIAN = sys.byteorder == "big"
9del sys
10verify((struct.pack('=i', 1)[0] == chr(0)) == ISBIGENDIAN,
11 "bigendian determination appears wrong")
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013PY_STRUCT_RANGE_CHECKING = 1
14
Tim Peters17e17d42001-06-13 22:45:27 +000015def string_reverse(s):
16 chars = list(s)
17 chars.reverse()
18 return "".join(chars)
19
20def bigendian_to_native(value):
21 if ISBIGENDIAN:
22 return value
23 else:
24 return string_reverse(value)
25
Barry Warsaw07a0eec1996-12-12 23:34:06 +000026def simple_err(func, *args):
27 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +000028 func(*args)
Barry Warsaw07a0eec1996-12-12 23:34:06 +000029 except struct.error:
Guido van Rossum41360a41998-03-26 19:42:58 +000030 pass
Barry Warsaw07a0eec1996-12-12 23:34:06 +000031 else:
Guido van Rossum41360a41998-03-26 19:42:58 +000032 raise TestFailed, "%s%s did not raise struct.error" % (
33 func.__name__, args)
Barry Warsaw07a0eec1996-12-12 23:34:06 +000034
Tim Peters7a3bfc32001-06-12 01:22:22 +000035def any_err(func, *args):
36 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +000037 func(*args)
Tim Peters7a3bfc32001-06-12 01:22:22 +000038 except (struct.error, OverflowError, TypeError):
39 pass
40 else:
41 raise TestFailed, "%s%s did not raise error" % (
42 func.__name__, args)
Tim Peters7a3bfc32001-06-12 01:22:22 +000043
Tim Peters17e17d42001-06-13 22:45:27 +000044
Tim Peters7b9542a2001-06-10 23:40:19 +000045simple_err(struct.calcsize, 'Z')
Barry Warsaw07a0eec1996-12-12 23:34:06 +000046
47sz = struct.calcsize('i')
Fred Drake132dce22000-12-12 23:11:42 +000048if sz * 3 != struct.calcsize('iii'):
Guido van Rossum2a378501996-12-31 17:25:47 +000049 raise TestFailed, 'inconsistent sizes'
Barry Warsaw07a0eec1996-12-12 23:34:06 +000050
Guido van Rossum04ebf5c1997-01-03 19:00:37 +000051fmt = 'cbxxxxxxhhhhiillffd'
52fmt3 = '3c3b18x12h6i6l6f3d'
53sz = struct.calcsize(fmt)
54sz3 = struct.calcsize(fmt3)
Fred Drake132dce22000-12-12 23:11:42 +000055if sz * 3 != sz3:
Walter Dörwald70a6b492004-02-12 17:35:32 +000056 raise TestFailed, 'inconsistent sizes (3*%r -> 3*%d = %d, %r -> %d)' % (
57 fmt, sz, 3*sz, fmt3, sz3)
Barry Warsaw07a0eec1996-12-12 23:34:06 +000058
59simple_err(struct.pack, 'iii', 3)
60simple_err(struct.pack, 'i', 3, 3, 3)
61simple_err(struct.pack, 'i', 'foo')
Armin Rigo9f904392004-09-27 19:27:51 +000062simple_err(struct.pack, 'P', 'foo')
Barry Warsaw07a0eec1996-12-12 23:34:06 +000063simple_err(struct.unpack, 'd', 'flap')
64s = struct.pack('ii', 1, 2)
65simple_err(struct.unpack, 'iii', s)
66simple_err(struct.unpack, 'i', s)
67
68c = 'a'
Guido van Rossum2a378501996-12-31 17:25:47 +000069b = 1
Barry Warsaw07a0eec1996-12-12 23:34:06 +000070h = 255
71i = 65535
72l = 65536
73f = 3.1415
74d = 3.1415
75
Guido van Rossum420c11c1997-01-03 00:09:46 +000076for prefix in ('', '@', '<', '>', '=', '!'):
77 for format in ('xcbhilfd', 'xcBHILfd'):
Guido van Rossum41360a41998-03-26 19:42:58 +000078 format = prefix + format
79 if verbose:
80 print "trying:", format
81 s = struct.pack(format, c, b, h, i, l, f, d)
82 cp, bp, hp, ip, lp, fp, dp = struct.unpack(format, s)
Fred Drake132dce22000-12-12 23:11:42 +000083 if (cp != c or bp != b or hp != h or ip != i or lp != l or
84 int(100 * fp) != int(100 * f) or int(100 * dp) != int(100 * d)):
Guido van Rossum41360a41998-03-26 19:42:58 +000085 # ^^^ calculate only to two decimal places
86 raise TestFailed, "unpack/pack not transitive (%s, %s)" % (
87 str(format), str((cp, bp, hp, ip, lp, fp, dp)))
Guido van Rossum2a378501996-12-31 17:25:47 +000088
Guido van Rossum420c11c1997-01-03 00:09:46 +000089# Test some of the new features in detail
Guido van Rossum2a378501996-12-31 17:25:47 +000090
91# (format, argument, big-endian result, little-endian result, asymmetric)
92tests = [
93 ('c', 'a', 'a', 'a', 0),
94 ('xc', 'a', '\0a', '\0a', 0),
95 ('cx', 'a', 'a\0', 'a\0', 0),
96 ('s', 'a', 'a', 'a', 0),
97 ('0s', 'helloworld', '', '', 1),
98 ('1s', 'helloworld', 'h', 'h', 1),
99 ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
100 ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
101 ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
102 ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
103 ('b', 7, '\7', '\7', 0),
104 ('b', -7, '\371', '\371', 0),
105 ('B', 7, '\7', '\7', 0),
106 ('B', 249, '\371', '\371', 0),
107 ('h', 700, '\002\274', '\274\002', 0),
108 ('h', -700, '\375D', 'D\375', 0),
109 ('H', 700, '\002\274', '\274\002', 0),
110 ('H', 0x10000-700, '\375D', 'D\375', 0),
111 ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
112 ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
113 ('I', 70000000L, '\004,\035\200', '\200\035,\004', 0),
114 ('I', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
115 ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
116 ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
117 ('L', 70000000L, '\004,\035\200', '\200\035,\004', 0),
118 ('L', 0x100000000L-70000000, '\373\323\342\200', '\200\342\323\373', 0),
Guido van Rossum420c11c1997-01-03 00:09:46 +0000119 ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
120 ('d', 2.0, '@\000\000\000\000\000\000\000',
121 '\000\000\000\000\000\000\000@', 0),
122 ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
123 ('d', -2.0, '\300\000\000\000\000\000\000\000',
124 '\000\000\000\000\000\000\000\300', 0),
Guido van Rossum2a378501996-12-31 17:25:47 +0000125]
126
Guido van Rossum2a378501996-12-31 17:25:47 +0000127for fmt, arg, big, lil, asy in tests:
128 if verbose:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000129 print "%r %r %r %r" % (fmt, arg, big, lil)
Guido van Rossum2a378501996-12-31 17:25:47 +0000130 for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
Tim Peters17e17d42001-06-13 22:45:27 +0000131 ('='+fmt, ISBIGENDIAN and big or lil)]:
Guido van Rossum41360a41998-03-26 19:42:58 +0000132 res = struct.pack(xfmt, arg)
133 if res != exp:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000134 raise TestFailed, "pack(%r, %r) -> %r # expected %r" % (
135 fmt, arg, res, exp)
Guido van Rossum41360a41998-03-26 19:42:58 +0000136 n = struct.calcsize(xfmt)
137 if n != len(res):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000138 raise TestFailed, "calcsize(%r) -> %d # expected %d" % (
139 xfmt, n, len(res))
Guido van Rossum41360a41998-03-26 19:42:58 +0000140 rev = struct.unpack(xfmt, res)[0]
141 if rev != arg and not asy:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000142 raise TestFailed, "unpack(%r, %r) -> (%r,) # expected (%r,)" % (
143 fmt, res, rev, arg)
Tim Peters7b9542a2001-06-10 23:40:19 +0000144
Tim Peters7a3bfc32001-06-12 01:22:22 +0000145###########################################################################
Tim Peters17e17d42001-06-13 22:45:27 +0000146# Simple native q/Q tests.
Tim Peters7b9542a2001-06-10 23:40:19 +0000147
148has_native_qQ = 1
149try:
150 struct.pack("q", 5)
151except struct.error:
152 has_native_qQ = 0
153
154if verbose:
155 print "Platform has native q/Q?", has_native_qQ and "Yes." or "No."
156
Tim Peters7a3bfc32001-06-12 01:22:22 +0000157any_err(struct.pack, "Q", -1) # can't pack -1 as unsigned regardless
Tim Peters7b9542a2001-06-10 23:40:19 +0000158simple_err(struct.pack, "q", "a") # can't pack string as 'q' regardless
159simple_err(struct.pack, "Q", "a") # ditto, but 'Q'
160
Tim Peters7a3bfc32001-06-12 01:22:22 +0000161def test_native_qQ():
Tim Peters7b9542a2001-06-10 23:40:19 +0000162 bytes = struct.calcsize('q')
163 # The expected values here are in big-endian format, primarily because
164 # I'm on a little-endian machine and so this is the clearest way (for
165 # me) to force the code to get exercised.
166 for format, input, expected in (
167 ('q', -1, '\xff' * bytes),
168 ('q', 0, '\x00' * bytes),
169 ('Q', 0, '\x00' * bytes),
170 ('q', 1L, '\x00' * (bytes-1) + '\x01'),
171 ('Q', (1L << (8*bytes))-1, '\xff' * bytes),
172 ('q', (1L << (8*bytes-1))-1, '\x7f' + '\xff' * (bytes - 1))):
173 got = struct.pack(format, input)
Tim Petersc533edc2001-06-10 23:52:59 +0000174 native_expected = bigendian_to_native(expected)
175 verify(got == native_expected,
Tim Peters7b9542a2001-06-10 23:40:19 +0000176 "%r-pack of %r gave %r, not %r" %
Tim Petersc533edc2001-06-10 23:52:59 +0000177 (format, input, got, native_expected))
Tim Peters7b9542a2001-06-10 23:40:19 +0000178 retrieved = struct.unpack(format, got)[0]
179 verify(retrieved == input,
180 "%r-unpack of %r gave %r, not %r" %
181 (format, got, retrieved, input))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000182
183if has_native_qQ:
184 test_native_qQ()
185
Tim Peters17e17d42001-06-13 22:45:27 +0000186###########################################################################
187# Standard integer tests (bBhHiIlLqQ).
Tim Peters7a3bfc32001-06-12 01:22:22 +0000188
189import binascii
Tim Peters7a3bfc32001-06-12 01:22:22 +0000190
Tim Peters17e17d42001-06-13 22:45:27 +0000191class IntTester:
Tim Peters7a3bfc32001-06-12 01:22:22 +0000192
Tim Peters17e17d42001-06-13 22:45:27 +0000193 # XXX Most std integer modes fail to test for out-of-range.
Tim Peters3eec38a2001-06-18 22:27:39 +0000194 # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but
195 # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C
196 # reported by Mark Favas).
197 BUGGY_RANGE_CHECK = "bBhHiIlL"
Tim Peters7a3bfc32001-06-12 01:22:22 +0000198
Tim Peters17e17d42001-06-13 22:45:27 +0000199 def __init__(self, formatpair, bytesize):
200 assert len(formatpair) == 2
201 self.formatpair = formatpair
202 for direction in "<>!=":
203 for code in formatpair:
204 format = direction + code
205 verify(struct.calcsize(format) == bytesize)
206 self.bytesize = bytesize
207 self.bitsize = bytesize * 8
208 self.signed_code, self.unsigned_code = formatpair
209 self.unsigned_min = 0
210 self.unsigned_max = 2L**self.bitsize - 1
211 self.signed_min = -(2L**(self.bitsize-1))
212 self.signed_max = 2L**(self.bitsize-1) - 1
Tim Peters7a3bfc32001-06-12 01:22:22 +0000213
Tim Peters17e17d42001-06-13 22:45:27 +0000214 def test_one(self, x, pack=struct.pack,
215 unpack=struct.unpack,
216 unhexlify=binascii.unhexlify):
217 if verbose:
218 print "trying std", self.formatpair, "on", x, "==", hex(x)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000219
Tim Peters17e17d42001-06-13 22:45:27 +0000220 # Try signed.
221 code = self.signed_code
222 if self.signed_min <= x <= self.signed_max:
223 # Try big-endian.
224 expected = long(x)
225 if x < 0:
226 expected += 1L << self.bitsize
227 assert expected > 0
228 expected = hex(expected)[2:-1] # chop "0x" and trailing 'L'
229 if len(expected) & 1:
230 expected = "0" + expected
231 expected = unhexlify(expected)
232 expected = "\x00" * (self.bytesize - len(expected)) + expected
Tim Peters7a3bfc32001-06-12 01:22:22 +0000233
Tim Peters17e17d42001-06-13 22:45:27 +0000234 # Pack work?
235 format = ">" + code
236 got = pack(format, x)
237 verify(got == expected,
238 "'%s'-pack of %r gave %r, not %r" %
239 (format, x, got, expected))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000240
Tim Peters17e17d42001-06-13 22:45:27 +0000241 # Unpack work?
242 retrieved = unpack(format, got)[0]
243 verify(x == retrieved,
244 "'%s'-unpack of %r gave %r, not %r" %
245 (format, got, retrieved, x))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000246
Tim Peters17e17d42001-06-13 22:45:27 +0000247 # Adding any byte should cause a "too big" error.
248 any_err(unpack, format, '\x01' + got)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000249
Tim Peters17e17d42001-06-13 22:45:27 +0000250 # Try little-endian.
251 format = "<" + code
252 expected = string_reverse(expected)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000253
Tim Peters17e17d42001-06-13 22:45:27 +0000254 # Pack work?
255 got = pack(format, x)
256 verify(got == expected,
257 "'%s'-pack of %r gave %r, not %r" %
258 (format, x, got, expected))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000259
Tim Peters17e17d42001-06-13 22:45:27 +0000260 # Unpack work?
261 retrieved = unpack(format, got)[0]
262 verify(x == retrieved,
263 "'%s'-unpack of %r gave %r, not %r" %
264 (format, got, retrieved, x))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000265
Tim Peters17e17d42001-06-13 22:45:27 +0000266 # Adding any byte should cause a "too big" error.
267 any_err(unpack, format, '\x01' + got)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000268
Tim Peters17e17d42001-06-13 22:45:27 +0000269 else:
270 # x is out of range -- verify pack realizes that.
Thomas Wouters477c8d52006-05-27 19:21:47 +0000271 if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
Tim Peters17e17d42001-06-13 22:45:27 +0000272 if verbose:
273 print "Skipping buggy range check for code", code
274 else:
275 any_err(pack, ">" + code, x)
276 any_err(pack, "<" + code, x)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000277
Tim Peters17e17d42001-06-13 22:45:27 +0000278 # Much the same for unsigned.
279 code = self.unsigned_code
280 if self.unsigned_min <= x <= self.unsigned_max:
281 # Try big-endian.
282 format = ">" + code
283 expected = long(x)
284 expected = hex(expected)[2:-1] # chop "0x" and trailing 'L'
285 if len(expected) & 1:
286 expected = "0" + expected
287 expected = unhexlify(expected)
288 expected = "\x00" * (self.bytesize - len(expected)) + expected
Tim Peters7a3bfc32001-06-12 01:22:22 +0000289
Tim Peters17e17d42001-06-13 22:45:27 +0000290 # Pack work?
291 got = pack(format, x)
292 verify(got == expected,
293 "'%s'-pack of %r gave %r, not %r" %
294 (format, x, got, expected))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000295
Tim Peters17e17d42001-06-13 22:45:27 +0000296 # Unpack work?
297 retrieved = unpack(format, got)[0]
298 verify(x == retrieved,
299 "'%s'-unpack of %r gave %r, not %r" %
300 (format, got, retrieved, x))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000301
Tim Peters17e17d42001-06-13 22:45:27 +0000302 # Adding any byte should cause a "too big" error.
303 any_err(unpack, format, '\x01' + got)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000304
Tim Peters17e17d42001-06-13 22:45:27 +0000305 # Try little-endian.
306 format = "<" + code
307 expected = string_reverse(expected)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000308
Tim Peters17e17d42001-06-13 22:45:27 +0000309 # Pack work?
310 got = pack(format, x)
311 verify(got == expected,
312 "'%s'-pack of %r gave %r, not %r" %
313 (format, x, got, expected))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000314
Tim Peters17e17d42001-06-13 22:45:27 +0000315 # Unpack work?
316 retrieved = unpack(format, got)[0]
317 verify(x == retrieved,
318 "'%s'-unpack of %r gave %r, not %r" %
319 (format, got, retrieved, x))
Tim Peters7a3bfc32001-06-12 01:22:22 +0000320
Tim Peters17e17d42001-06-13 22:45:27 +0000321 # Adding any byte should cause a "too big" error.
322 any_err(unpack, format, '\x01' + got)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000323
Tim Peters17e17d42001-06-13 22:45:27 +0000324 else:
325 # x is out of range -- verify pack realizes that.
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326 if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
Tim Peters17e17d42001-06-13 22:45:27 +0000327 if verbose:
328 print "Skipping buggy range check for code", code
329 else:
330 any_err(pack, ">" + code, x)
331 any_err(pack, "<" + code, x)
Tim Peters7a3bfc32001-06-12 01:22:22 +0000332
Tim Peters17e17d42001-06-13 22:45:27 +0000333 def run(self):
334 from random import randrange
335
336 # Create all interesting powers of 2.
337 values = []
338 for exp in range(self.bitsize + 3):
339 values.append(1L << exp)
340
341 # Add some random values.
342 for i in range(self.bitsize):
343 val = 0L
344 for j in range(self.bytesize):
345 val = (val << 8) | randrange(256)
346 values.append(val)
347
348 # Try all those, and their negations, and +-1 from them. Note
349 # that this tests all power-of-2 boundaries in range, and a few out
350 # of range, plus +-(2**n +- 1).
351 for base in values:
352 for val in -base, base:
353 for incr in -1, 0, 1:
354 x = val + incr
355 try:
356 x = int(x)
357 except OverflowError:
358 pass
359 self.test_one(x)
360
361 # Some error cases.
362 for direction in "<>":
363 for code in self.formatpair:
364 for badobject in "a string", 3+42j, randrange:
365 any_err(struct.pack, direction + code, badobject)
366
367for args in [("bB", 1),
368 ("hH", 2),
369 ("iI", 4),
370 ("lL", 4),
371 ("qQ", 8)]:
372 t = IntTester(*args)
373 t.run()
Tim Peters0891ac02001-09-15 02:35:15 +0000374
375
376###########################################################################
377# The p ("Pascal string") code.
378
379def test_p_code():
380 for code, input, expected, expectedback in [
381 ('p','abc', '\x00', ''),
382 ('1p', 'abc', '\x00', ''),
383 ('2p', 'abc', '\x01a', 'a'),
384 ('3p', 'abc', '\x02ab', 'ab'),
385 ('4p', 'abc', '\x03abc', 'abc'),
386 ('5p', 'abc', '\x03abc\x00', 'abc'),
387 ('6p', 'abc', '\x03abc\x00\x00', 'abc'),
388 ('1000p', 'x'*1000, '\xff' + 'x'*999, 'x'*255)]:
389 got = struct.pack(code, input)
390 if got != expected:
391 raise TestFailed("pack(%r, %r) == %r but expected %r" %
392 (code, input, got, expected))
393 (got,) = struct.unpack(code, got)
394 if got != expectedback:
395 raise TestFailed("unpack(%r, %r) == %r but expected %r" %
396 (code, input, got, expectedback))
397
398test_p_code()
Tim Petersd50ade62003-03-20 18:32:13 +0000399
400
401###########################################################################
402# SF bug 705836. "<f" and ">f" had a severe rounding bug, where a carry
403# from the low-order discarded bits could propagate into the exponent
404# field, causing the result to be wrong by a factor of 2.
405
406def test_705836():
407 import math
408
409 for base in range(1, 33):
410 # smaller <- largest representable float less than base.
411 delta = 0.5
412 while base - delta / 2.0 != base:
413 delta /= 2.0
414 smaller = base - delta
415 # Packing this rounds away a solid string of trailing 1 bits.
416 packed = struct.pack("<f", smaller)
417 unpacked = struct.unpack("<f", packed)[0]
418 # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
419 # 16, respectively.
420 verify(base == unpacked)
421 bigpacked = struct.pack(">f", smaller)
422 verify(bigpacked == string_reverse(packed),
423 ">f pack should be byte-reversal of <f pack")
424 unpacked = struct.unpack(">f", bigpacked)[0]
425 verify(base == unpacked)
426
427 # Largest finite IEEE single.
428 big = (1 << 24) - 1
429 big = math.ldexp(big, 127 - 23)
430 packed = struct.pack(">f", big)
431 unpacked = struct.unpack(">f", packed)[0]
432 verify(big == unpacked)
433
434 # The same, but tack on a 1 bit so it rounds up to infinity.
435 big = (1 << 25) - 1
436 big = math.ldexp(big, 127 - 24)
437 try:
438 packed = struct.pack(">f", big)
439 except OverflowError:
440 pass
441 else:
442 TestFailed("expected OverflowError")
443
444test_705836()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000445
446def test_1229380():
447 import sys
448 for endian in ('', '>', '<'):
449 for cls in (int, long):
450 for fmt in ('B', 'H', 'I', 'L'):
451 any_err(struct.pack, endian + fmt, cls(-1))
452
453 any_err(struct.pack, endian + 'B', cls(300))
454 any_err(struct.pack, endian + 'H', cls(70000))
455
456 any_err(struct.pack, endian + 'I', sys.maxint * 4L)
457 any_err(struct.pack, endian + 'L', sys.maxint * 4L)
458
459if PY_STRUCT_RANGE_CHECKING:
460 test_1229380()
461
462class PackBufferTestCase(unittest.TestCase):
463 """
464 Test the packing methods that work on buffers.
465 """
466
467 def test_unpack_from( self ):
468 test_string = 'abcd01234'
469 fmt = '4s'
470 s = struct.Struct(fmt)
471 for cls in (str, buffer):
472 data = cls(test_string)
473 self.assertEquals(s.unpack_from(data), ('abcd',))
474 self.assertEquals(s.unpack_from(data, 2), ('cd01',))
475 self.assertEquals(s.unpack_from(data, 4), ('0123',))
476 for i in xrange(6):
477 self.assertEquals(s.unpack_from(data, i), (data[i:i+4],))
478 for i in xrange(6, len(test_string) + 1):
479 simple_err(s.unpack_from, data, i)
480 for cls in (str, buffer):
481 data = cls(test_string)
482 self.assertEquals(struct.unpack_from(fmt, data), ('abcd',))
483 self.assertEquals(struct.unpack_from(fmt, data, 2), ('cd01',))
484 self.assertEquals(struct.unpack_from(fmt, data, 4), ('0123',))
485 for i in xrange(6):
486 self.assertEquals(struct.unpack_from(fmt, data, i),
487 (data[i:i+4],))
488 for i in xrange(6, len(test_string) + 1):
489 simple_err(struct.unpack_from, fmt, data, i)
490
491 def test_pack_to( self ):
492 test_string = 'Reykjavik rocks, eow!'
493 writable_buf = array.array('c', ' '*100)
494 fmt = '21s'
495 s = struct.Struct(fmt)
496
497 # Test without offset
498 s.pack_to(writable_buf, 0, test_string)
499 from_buf = writable_buf.tostring()[:len(test_string)]
500 self.assertEquals(from_buf, test_string)
501
502 # Test with offset.
503 s.pack_to(writable_buf, 10, test_string)
504 from_buf = writable_buf.tostring()[:len(test_string)+10]
505 self.assertEquals(from_buf, (test_string[:10] + test_string))
506
507 # Go beyond boundaries.
508 small_buf = array.array('c', ' '*10)
509 self.assertRaises(struct.error, s.pack_to, small_buf, 0, test_string)
510 self.assertRaises(struct.error, s.pack_to, small_buf, 2, test_string)
511
512 def test_pack_to_fn( self ):
513 test_string = 'Reykjavik rocks, eow!'
514 writable_buf = array.array('c', ' '*100)
515 fmt = '21s'
516 pack_to = lambda *args: struct.pack_to(fmt, *args)
517
518 # Test without offset
519 pack_to(writable_buf, 0, test_string)
520 from_buf = writable_buf.tostring()[:len(test_string)]
521 self.assertEquals(from_buf, test_string)
522
523 # Test with offset.
524 pack_to(writable_buf, 10, test_string)
525 from_buf = writable_buf.tostring()[:len(test_string)+10]
526 self.assertEquals(from_buf, (test_string[:10] + test_string))
527
528 # Go beyond boundaries.
529 small_buf = array.array('c', ' '*10)
530 self.assertRaises(struct.error, pack_to, small_buf, 0, test_string)
531 self.assertRaises(struct.error, pack_to, small_buf, 2, test_string)
532
533
534def test_main():
535 test.test_support.run_unittest(PackBufferTestCase)
536
537if __name__ == "__main__":
538 test_main()