]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/test/pickletester.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / pickletester.py
CommitLineData
4710c53d 1import unittest\r
2import pickle\r
3import cPickle\r
4import StringIO\r
5import cStringIO\r
6import pickletools\r
7import copy_reg\r
8\r
9from test.test_support import TestFailed, have_unicode, TESTFN\r
10\r
11# Tests that try a number of pickle protocols should have a\r
12# for proto in protocols:\r
13# kind of outer loop.\r
14assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2\r
15protocols = range(pickle.HIGHEST_PROTOCOL + 1)\r
16\r
17# Copy of test.test_support.run_with_locale. This is needed to support Python\r
18# 2.4, which didn't include it. This is all to support test_xpickle, which\r
19# bounces pickled objects through older Python versions to test backwards\r
20# compatibility.\r
21def run_with_locale(catstr, *locales):\r
22 def decorator(func):\r
23 def inner(*args, **kwds):\r
24 try:\r
25 import locale\r
26 category = getattr(locale, catstr)\r
27 orig_locale = locale.setlocale(category)\r
28 except AttributeError:\r
29 # if the test author gives us an invalid category string\r
30 raise\r
31 except:\r
32 # cannot retrieve original locale, so do nothing\r
33 locale = orig_locale = None\r
34 else:\r
35 for loc in locales:\r
36 try:\r
37 locale.setlocale(category, loc)\r
38 break\r
39 except:\r
40 pass\r
41\r
42 # now run the function, resetting the locale on exceptions\r
43 try:\r
44 return func(*args, **kwds)\r
45 finally:\r
46 if locale and orig_locale:\r
47 locale.setlocale(category, orig_locale)\r
48 inner.func_name = func.func_name\r
49 inner.__doc__ = func.__doc__\r
50 return inner\r
51 return decorator\r
52\r
53\r
54# Return True if opcode code appears in the pickle, else False.\r
55def opcode_in_pickle(code, pickle):\r
56 for op, dummy, dummy in pickletools.genops(pickle):\r
57 if op.code == code:\r
58 return True\r
59 return False\r
60\r
61# Return the number of times opcode code appears in pickle.\r
62def count_opcode(code, pickle):\r
63 n = 0\r
64 for op, dummy, dummy in pickletools.genops(pickle):\r
65 if op.code == code:\r
66 n += 1\r
67 return n\r
68\r
69# We can't very well test the extension registry without putting known stuff\r
70# in it, but we have to be careful to restore its original state. Code\r
71# should do this:\r
72#\r
73# e = ExtensionSaver(extension_code)\r
74# try:\r
75# fiddle w/ the extension registry's stuff for extension_code\r
76# finally:\r
77# e.restore()\r
78\r
79class ExtensionSaver:\r
80 # Remember current registration for code (if any), and remove it (if\r
81 # there is one).\r
82 def __init__(self, code):\r
83 self.code = code\r
84 if code in copy_reg._inverted_registry:\r
85 self.pair = copy_reg._inverted_registry[code]\r
86 copy_reg.remove_extension(self.pair[0], self.pair[1], code)\r
87 else:\r
88 self.pair = None\r
89\r
90 # Restore previous registration for code.\r
91 def restore(self):\r
92 code = self.code\r
93 curpair = copy_reg._inverted_registry.get(code)\r
94 if curpair is not None:\r
95 copy_reg.remove_extension(curpair[0], curpair[1], code)\r
96 pair = self.pair\r
97 if pair is not None:\r
98 copy_reg.add_extension(pair[0], pair[1], code)\r
99\r
100class C:\r
101 def __cmp__(self, other):\r
102 return cmp(self.__dict__, other.__dict__)\r
103\r
104import __main__\r
105__main__.C = C\r
106C.__module__ = "__main__"\r
107\r
108class myint(int):\r
109 def __init__(self, x):\r
110 self.str = str(x)\r
111\r
112class initarg(C):\r
113\r
114 def __init__(self, a, b):\r
115 self.a = a\r
116 self.b = b\r
117\r
118 def __getinitargs__(self):\r
119 return self.a, self.b\r
120\r
121class metaclass(type):\r
122 pass\r
123\r
124class use_metaclass(object):\r
125 __metaclass__ = metaclass\r
126\r
127# DATA0 .. DATA2 are the pickles we expect under the various protocols, for\r
128# the object returned by create_data().\r
129\r
130# break into multiple strings to avoid confusing font-lock-mode\r
131DATA0 = """(lp1\r
132I0\r
133aL1L\r
134aF2\r
135ac__builtin__\r
136complex\r
137p2\r
138""" + \\r
139"""(F3\r
140F0\r
141tRp3\r
142aI1\r
143aI-1\r
144aI255\r
145aI-255\r
146aI-256\r
147aI65535\r
148aI-65535\r
149aI-65536\r
150aI2147483647\r
151aI-2147483647\r
152aI-2147483648\r
153a""" + \\r
154"""(S'abc'\r
155p4\r
156g4\r
157""" + \\r
158"""(i__main__\r
159C\r
160p5\r
161""" + \\r
162"""(dp6\r
163S'foo'\r
164p7\r
165I1\r
166sS'bar'\r
167p8\r
168I2\r
169sbg5\r
170tp9\r
171ag9\r
172aI5\r
173a.\r
174"""\r
175\r
176# Disassembly of DATA0.\r
177DATA0_DIS = """\\r
178 0: ( MARK\r
179 1: l LIST (MARK at 0)\r
180 2: p PUT 1\r
181 5: I INT 0\r
182 8: a APPEND\r
183 9: L LONG 1L\r
184 13: a APPEND\r
185 14: F FLOAT 2.0\r
186 17: a APPEND\r
187 18: c GLOBAL '__builtin__ complex'\r
188 39: p PUT 2\r
189 42: ( MARK\r
190 43: F FLOAT 3.0\r
191 46: F FLOAT 0.0\r
192 49: t TUPLE (MARK at 42)\r
193 50: R REDUCE\r
194 51: p PUT 3\r
195 54: a APPEND\r
196 55: I INT 1\r
197 58: a APPEND\r
198 59: I INT -1\r
199 63: a APPEND\r
200 64: I INT 255\r
201 69: a APPEND\r
202 70: I INT -255\r
203 76: a APPEND\r
204 77: I INT -256\r
205 83: a APPEND\r
206 84: I INT 65535\r
207 91: a APPEND\r
208 92: I INT -65535\r
209 100: a APPEND\r
210 101: I INT -65536\r
211 109: a APPEND\r
212 110: I INT 2147483647\r
213 122: a APPEND\r
214 123: I INT -2147483647\r
215 136: a APPEND\r
216 137: I INT -2147483648\r
217 150: a APPEND\r
218 151: ( MARK\r
219 152: S STRING 'abc'\r
220 159: p PUT 4\r
221 162: g GET 4\r
222 165: ( MARK\r
223 166: i INST '__main__ C' (MARK at 165)\r
224 178: p PUT 5\r
225 181: ( MARK\r
226 182: d DICT (MARK at 181)\r
227 183: p PUT 6\r
228 186: S STRING 'foo'\r
229 193: p PUT 7\r
230 196: I INT 1\r
231 199: s SETITEM\r
232 200: S STRING 'bar'\r
233 207: p PUT 8\r
234 210: I INT 2\r
235 213: s SETITEM\r
236 214: b BUILD\r
237 215: g GET 5\r
238 218: t TUPLE (MARK at 151)\r
239 219: p PUT 9\r
240 222: a APPEND\r
241 223: g GET 9\r
242 226: a APPEND\r
243 227: I INT 5\r
244 230: a APPEND\r
245 231: . STOP\r
246highest protocol among opcodes = 0\r
247"""\r
248\r
249DATA1 = (']q\x01(K\x00L1L\nG@\x00\x00\x00\x00\x00\x00\x00'\r
250 'c__builtin__\ncomplex\nq\x02(G@\x08\x00\x00\x00\x00\x00'\r
251 '\x00G\x00\x00\x00\x00\x00\x00\x00\x00tRq\x03K\x01J\xff\xff'\r
252 '\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xff'\r
253 'J\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00'\r
254 '\x00\x80J\x00\x00\x00\x80(U\x03abcq\x04h\x04(c__main__\n'\r
255 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh'\r
256 '\x06tq\nh\nK\x05e.'\r
257 )\r
258\r
259# Disassembly of DATA1.\r
260DATA1_DIS = """\\r
261 0: ] EMPTY_LIST\r
262 1: q BINPUT 1\r
263 3: ( MARK\r
264 4: K BININT1 0\r
265 6: L LONG 1L\r
266 10: G BINFLOAT 2.0\r
267 19: c GLOBAL '__builtin__ complex'\r
268 40: q BINPUT 2\r
269 42: ( MARK\r
270 43: G BINFLOAT 3.0\r
271 52: G BINFLOAT 0.0\r
272 61: t TUPLE (MARK at 42)\r
273 62: R REDUCE\r
274 63: q BINPUT 3\r
275 65: K BININT1 1\r
276 67: J BININT -1\r
277 72: K BININT1 255\r
278 74: J BININT -255\r
279 79: J BININT -256\r
280 84: M BININT2 65535\r
281 87: J BININT -65535\r
282 92: J BININT -65536\r
283 97: J BININT 2147483647\r
284 102: J BININT -2147483647\r
285 107: J BININT -2147483648\r
286 112: ( MARK\r
287 113: U SHORT_BINSTRING 'abc'\r
288 118: q BINPUT 4\r
289 120: h BINGET 4\r
290 122: ( MARK\r
291 123: c GLOBAL '__main__ C'\r
292 135: q BINPUT 5\r
293 137: o OBJ (MARK at 122)\r
294 138: q BINPUT 6\r
295 140: } EMPTY_DICT\r
296 141: q BINPUT 7\r
297 143: ( MARK\r
298 144: U SHORT_BINSTRING 'foo'\r
299 149: q BINPUT 8\r
300 151: K BININT1 1\r
301 153: U SHORT_BINSTRING 'bar'\r
302 158: q BINPUT 9\r
303 160: K BININT1 2\r
304 162: u SETITEMS (MARK at 143)\r
305 163: b BUILD\r
306 164: h BINGET 6\r
307 166: t TUPLE (MARK at 112)\r
308 167: q BINPUT 10\r
309 169: h BINGET 10\r
310 171: K BININT1 5\r
311 173: e APPENDS (MARK at 3)\r
312 174: . STOP\r
313highest protocol among opcodes = 1\r
314"""\r
315\r
316DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00'\r
317 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00'\r
318 '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK'\r
319 '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff'\r
320 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00'\r
321 '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo'\r
322 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.')\r
323\r
324# Disassembly of DATA2.\r
325DATA2_DIS = """\\r
326 0: \x80 PROTO 2\r
327 2: ] EMPTY_LIST\r
328 3: q BINPUT 1\r
329 5: ( MARK\r
330 6: K BININT1 0\r
331 8: \x8a LONG1 1L\r
332 11: G BINFLOAT 2.0\r
333 20: c GLOBAL '__builtin__ complex'\r
334 41: q BINPUT 2\r
335 43: G BINFLOAT 3.0\r
336 52: G BINFLOAT 0.0\r
337 61: \x86 TUPLE2\r
338 62: R REDUCE\r
339 63: q BINPUT 3\r
340 65: K BININT1 1\r
341 67: J BININT -1\r
342 72: K BININT1 255\r
343 74: J BININT -255\r
344 79: J BININT -256\r
345 84: M BININT2 65535\r
346 87: J BININT -65535\r
347 92: J BININT -65536\r
348 97: J BININT 2147483647\r
349 102: J BININT -2147483647\r
350 107: J BININT -2147483648\r
351 112: ( MARK\r
352 113: U SHORT_BINSTRING 'abc'\r
353 118: q BINPUT 4\r
354 120: h BINGET 4\r
355 122: ( MARK\r
356 123: c GLOBAL '__main__ C'\r
357 135: q BINPUT 5\r
358 137: o OBJ (MARK at 122)\r
359 138: q BINPUT 6\r
360 140: } EMPTY_DICT\r
361 141: q BINPUT 7\r
362 143: ( MARK\r
363 144: U SHORT_BINSTRING 'foo'\r
364 149: q BINPUT 8\r
365 151: K BININT1 1\r
366 153: U SHORT_BINSTRING 'bar'\r
367 158: q BINPUT 9\r
368 160: K BININT1 2\r
369 162: u SETITEMS (MARK at 143)\r
370 163: b BUILD\r
371 164: h BINGET 6\r
372 166: t TUPLE (MARK at 112)\r
373 167: q BINPUT 10\r
374 169: h BINGET 10\r
375 171: K BININT1 5\r
376 173: e APPENDS (MARK at 5)\r
377 174: . STOP\r
378highest protocol among opcodes = 2\r
379"""\r
380\r
381def create_data():\r
382 c = C()\r
383 c.foo = 1\r
384 c.bar = 2\r
385 x = [0, 1L, 2.0, 3.0+0j]\r
386 # Append some integer test cases at cPickle.c's internal size\r
387 # cutoffs.\r
388 uint1max = 0xff\r
389 uint2max = 0xffff\r
390 int4max = 0x7fffffff\r
391 x.extend([1, -1,\r
392 uint1max, -uint1max, -uint1max-1,\r
393 uint2max, -uint2max, -uint2max-1,\r
394 int4max, -int4max, -int4max-1])\r
395 y = ('abc', 'abc', c, c)\r
396 x.append(y)\r
397 x.append(y)\r
398 x.append(5)\r
399 return x\r
400\r
401class AbstractPickleTests(unittest.TestCase):\r
402 # Subclass must define self.dumps, self.loads, self.error.\r
403\r
404 _testdata = create_data()\r
405\r
406 def setUp(self):\r
407 pass\r
408\r
409 def test_misc(self):\r
410 # test various datatypes not tested by testdata\r
411 for proto in protocols:\r
412 x = myint(4)\r
413 s = self.dumps(x, proto)\r
414 y = self.loads(s)\r
415 self.assertEqual(x, y)\r
416\r
417 x = (1, ())\r
418 s = self.dumps(x, proto)\r
419 y = self.loads(s)\r
420 self.assertEqual(x, y)\r
421\r
422 x = initarg(1, x)\r
423 s = self.dumps(x, proto)\r
424 y = self.loads(s)\r
425 self.assertEqual(x, y)\r
426\r
427 # XXX test __reduce__ protocol?\r
428\r
429 def test_roundtrip_equality(self):\r
430 expected = self._testdata\r
431 for proto in protocols:\r
432 s = self.dumps(expected, proto)\r
433 got = self.loads(s)\r
434 self.assertEqual(expected, got)\r
435\r
436 def test_load_from_canned_string(self):\r
437 expected = self._testdata\r
438 for canned in DATA0, DATA1, DATA2:\r
439 got = self.loads(canned)\r
440 self.assertEqual(expected, got)\r
441\r
442 # There are gratuitous differences between pickles produced by\r
443 # pickle and cPickle, largely because cPickle starts PUT indices at\r
444 # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() --\r
445 # there's a comment with an exclamation point there whose meaning\r
446 # is a mystery. cPickle also suppresses PUT for objects with a refcount\r
447 # of 1.\r
448 def dont_test_disassembly(self):\r
449 from pickletools import dis\r
450\r
451 for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):\r
452 s = self.dumps(self._testdata, proto)\r
453 filelike = cStringIO.StringIO()\r
454 dis(s, out=filelike)\r
455 got = filelike.getvalue()\r
456 self.assertEqual(expected, got)\r
457\r
458 def test_recursive_list(self):\r
459 l = []\r
460 l.append(l)\r
461 for proto in protocols:\r
462 s = self.dumps(l, proto)\r
463 x = self.loads(s)\r
464 self.assertEqual(len(x), 1)\r
465 self.assertTrue(x is x[0])\r
466\r
467 def test_recursive_tuple(self):\r
468 t = ([],)\r
469 t[0].append(t)\r
470 for proto in protocols:\r
471 s = self.dumps(t, proto)\r
472 x = self.loads(s)\r
473 self.assertEqual(len(x), 1)\r
474 self.assertEqual(len(x[0]), 1)\r
475 self.assertTrue(x is x[0][0])\r
476\r
477 def test_recursive_dict(self):\r
478 d = {}\r
479 d[1] = d\r
480 for proto in protocols:\r
481 s = self.dumps(d, proto)\r
482 x = self.loads(s)\r
483 self.assertEqual(x.keys(), [1])\r
484 self.assertTrue(x[1] is x)\r
485\r
486 def test_recursive_inst(self):\r
487 i = C()\r
488 i.attr = i\r
489 for proto in protocols:\r
490 s = self.dumps(i, 2)\r
491 x = self.loads(s)\r
492 self.assertEqual(dir(x), dir(i))\r
493 self.assertTrue(x.attr is x)\r
494\r
495 def test_recursive_multi(self):\r
496 l = []\r
497 d = {1:l}\r
498 i = C()\r
499 i.attr = d\r
500 l.append(i)\r
501 for proto in protocols:\r
502 s = self.dumps(l, proto)\r
503 x = self.loads(s)\r
504 self.assertEqual(len(x), 1)\r
505 self.assertEqual(dir(x[0]), dir(i))\r
506 self.assertEqual(x[0].attr.keys(), [1])\r
507 self.assertTrue(x[0].attr[1] is x)\r
508\r
509 def test_garyp(self):\r
510 self.assertRaises(self.error, self.loads, 'garyp')\r
511\r
512 def test_insecure_strings(self):\r
513 insecure = ["abc", "2 + 2", # not quoted\r
514 #"'abc' + 'def'", # not a single quoted string\r
515 "'abc", # quote is not closed\r
516 "'abc\"", # open quote and close quote don't match\r
517 "'abc' ?", # junk after close quote\r
518 "'\\'", # trailing backslash\r
519 # some tests of the quoting rules\r
520 #"'abc\"\''",\r
521 #"'\\\\a\'\'\'\\\'\\\\\''",\r
522 ]\r
523 for s in insecure:\r
524 buf = "S" + s + "\012p0\012."\r
525 self.assertRaises(ValueError, self.loads, buf)\r
526\r
527 if have_unicode:\r
528 def test_unicode(self):\r
529 endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>',\r
530 u'<\\>', u'<\\\U00012345>']\r
531 for proto in protocols:\r
532 for u in endcases:\r
533 p = self.dumps(u, proto)\r
534 u2 = self.loads(p)\r
535 self.assertEqual(u2, u)\r
536\r
537 def test_unicode_high_plane(self):\r
538 t = u'\U00012345'\r
539 for proto in protocols:\r
540 p = self.dumps(t, proto)\r
541 t2 = self.loads(p)\r
542 self.assertEqual(t2, t)\r
543\r
544 def test_ints(self):\r
545 import sys\r
546 for proto in protocols:\r
547 n = sys.maxint\r
548 while n:\r
549 for expected in (-n, n):\r
550 s = self.dumps(expected, proto)\r
551 n2 = self.loads(s)\r
552 self.assertEqual(expected, n2)\r
553 n = n >> 1\r
554\r
555 def test_maxint64(self):\r
556 maxint64 = (1L << 63) - 1\r
557 data = 'I' + str(maxint64) + '\n.'\r
558 got = self.loads(data)\r
559 self.assertEqual(got, maxint64)\r
560\r
561 # Try too with a bogus literal.\r
562 data = 'I' + str(maxint64) + 'JUNK\n.'\r
563 self.assertRaises(ValueError, self.loads, data)\r
564\r
565 def test_long(self):\r
566 for proto in protocols:\r
567 # 256 bytes is where LONG4 begins.\r
568 for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:\r
569 nbase = 1L << nbits\r
570 for npos in nbase-1, nbase, nbase+1:\r
571 for n in npos, -npos:\r
572 pickle = self.dumps(n, proto)\r
573 got = self.loads(pickle)\r
574 self.assertEqual(n, got)\r
575 # Try a monster. This is quadratic-time in protos 0 & 1, so don't\r
576 # bother with those.\r
577 nbase = long("deadbeeffeedface", 16)\r
578 nbase += nbase << 1000000\r
579 for n in nbase, -nbase:\r
580 p = self.dumps(n, 2)\r
581 got = self.loads(p)\r
582 self.assertEqual(n, got)\r
583\r
584 def test_float(self):\r
585 test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,\r
586 3.14, 263.44582062374053, 6.022e23, 1e30]\r
587 test_values = test_values + [-x for x in test_values]\r
588 for proto in protocols:\r
589 for value in test_values:\r
590 pickle = self.dumps(value, proto)\r
591 got = self.loads(pickle)\r
592 self.assertEqual(value, got)\r
593\r
594 @run_with_locale('LC_ALL', 'de_DE', 'fr_FR')\r
595 def test_float_format(self):\r
596 # make sure that floats are formatted locale independent\r
597 self.assertEqual(self.dumps(1.2)[0:3], 'F1.')\r
598\r
599 def test_reduce(self):\r
600 pass\r
601\r
602 def test_getinitargs(self):\r
603 pass\r
604\r
605 def test_metaclass(self):\r
606 a = use_metaclass()\r
607 for proto in protocols:\r
608 s = self.dumps(a, proto)\r
609 b = self.loads(s)\r
610 self.assertEqual(a.__class__, b.__class__)\r
611\r
612 def test_structseq(self):\r
613 import time\r
614 import os\r
615\r
616 t = time.localtime()\r
617 for proto in protocols:\r
618 s = self.dumps(t, proto)\r
619 u = self.loads(s)\r
620 self.assertEqual(t, u)\r
621 if hasattr(os, "stat"):\r
622 t = os.stat(os.curdir)\r
623 s = self.dumps(t, proto)\r
624 u = self.loads(s)\r
625 self.assertEqual(t, u)\r
626 if hasattr(os, "statvfs"):\r
627 t = os.statvfs(os.curdir)\r
628 s = self.dumps(t, proto)\r
629 u = self.loads(s)\r
630 self.assertEqual(t, u)\r
631\r
632 # Tests for protocol 2\r
633\r
634 def test_proto(self):\r
635 build_none = pickle.NONE + pickle.STOP\r
636 for proto in protocols:\r
637 expected = build_none\r
638 if proto >= 2:\r
639 expected = pickle.PROTO + chr(proto) + expected\r
640 p = self.dumps(None, proto)\r
641 self.assertEqual(p, expected)\r
642\r
643 oob = protocols[-1] + 1 # a future protocol\r
644 badpickle = pickle.PROTO + chr(oob) + build_none\r
645 try:\r
646 self.loads(badpickle)\r
647 except ValueError, detail:\r
648 self.assertTrue(str(detail).startswith(\r
649 "unsupported pickle protocol"))\r
650 else:\r
651 self.fail("expected bad protocol number to raise ValueError")\r
652\r
653 def test_long1(self):\r
654 x = 12345678910111213141516178920L\r
655 for proto in protocols:\r
656 s = self.dumps(x, proto)\r
657 y = self.loads(s)\r
658 self.assertEqual(x, y)\r
659 self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)\r
660\r
661 def test_long4(self):\r
662 x = 12345678910111213141516178920L << (256*8)\r
663 for proto in protocols:\r
664 s = self.dumps(x, proto)\r
665 y = self.loads(s)\r
666 self.assertEqual(x, y)\r
667 self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)\r
668\r
669 def test_short_tuples(self):\r
670 # Map (proto, len(tuple)) to expected opcode.\r
671 expected_opcode = {(0, 0): pickle.TUPLE,\r
672 (0, 1): pickle.TUPLE,\r
673 (0, 2): pickle.TUPLE,\r
674 (0, 3): pickle.TUPLE,\r
675 (0, 4): pickle.TUPLE,\r
676\r
677 (1, 0): pickle.EMPTY_TUPLE,\r
678 (1, 1): pickle.TUPLE,\r
679 (1, 2): pickle.TUPLE,\r
680 (1, 3): pickle.TUPLE,\r
681 (1, 4): pickle.TUPLE,\r
682\r
683 (2, 0): pickle.EMPTY_TUPLE,\r
684 (2, 1): pickle.TUPLE1,\r
685 (2, 2): pickle.TUPLE2,\r
686 (2, 3): pickle.TUPLE3,\r
687 (2, 4): pickle.TUPLE,\r
688 }\r
689 a = ()\r
690 b = (1,)\r
691 c = (1, 2)\r
692 d = (1, 2, 3)\r
693 e = (1, 2, 3, 4)\r
694 for proto in protocols:\r
695 for x in a, b, c, d, e:\r
696 s = self.dumps(x, proto)\r
697 y = self.loads(s)\r
698 self.assertEqual(x, y, (proto, x, s, y))\r
699 expected = expected_opcode[proto, len(x)]\r
700 self.assertEqual(opcode_in_pickle(expected, s), True)\r
701\r
702 def test_singletons(self):\r
703 # Map (proto, singleton) to expected opcode.\r
704 expected_opcode = {(0, None): pickle.NONE,\r
705 (1, None): pickle.NONE,\r
706 (2, None): pickle.NONE,\r
707\r
708 (0, True): pickle.INT,\r
709 (1, True): pickle.INT,\r
710 (2, True): pickle.NEWTRUE,\r
711\r
712 (0, False): pickle.INT,\r
713 (1, False): pickle.INT,\r
714 (2, False): pickle.NEWFALSE,\r
715 }\r
716 for proto in protocols:\r
717 for x in None, False, True:\r
718 s = self.dumps(x, proto)\r
719 y = self.loads(s)\r
720 self.assertTrue(x is y, (proto, x, s, y))\r
721 expected = expected_opcode[proto, x]\r
722 self.assertEqual(opcode_in_pickle(expected, s), True)\r
723\r
724 def test_newobj_tuple(self):\r
725 x = MyTuple([1, 2, 3])\r
726 x.foo = 42\r
727 x.bar = "hello"\r
728 for proto in protocols:\r
729 s = self.dumps(x, proto)\r
730 y = self.loads(s)\r
731 self.assertEqual(tuple(x), tuple(y))\r
732 self.assertEqual(x.__dict__, y.__dict__)\r
733\r
734 def test_newobj_list(self):\r
735 x = MyList([1, 2, 3])\r
736 x.foo = 42\r
737 x.bar = "hello"\r
738 for proto in protocols:\r
739 s = self.dumps(x, proto)\r
740 y = self.loads(s)\r
741 self.assertEqual(list(x), list(y))\r
742 self.assertEqual(x.__dict__, y.__dict__)\r
743\r
744 def test_newobj_generic(self):\r
745 for proto in protocols:\r
746 for C in myclasses:\r
747 B = C.__base__\r
748 x = C(C.sample)\r
749 x.foo = 42\r
750 s = self.dumps(x, proto)\r
751 y = self.loads(s)\r
752 detail = (proto, C, B, x, y, type(y))\r
753 self.assertEqual(B(x), B(y), detail)\r
754 self.assertEqual(x.__dict__, y.__dict__, detail)\r
755\r
756 # Register a type with copy_reg, with extension code extcode. Pickle\r
757 # an object of that type. Check that the resulting pickle uses opcode\r
758 # (EXT[124]) under proto 2, and not in proto 1.\r
759\r
760 def produce_global_ext(self, extcode, opcode):\r
761 e = ExtensionSaver(extcode)\r
762 try:\r
763 copy_reg.add_extension(__name__, "MyList", extcode)\r
764 x = MyList([1, 2, 3])\r
765 x.foo = 42\r
766 x.bar = "hello"\r
767\r
768 # Dump using protocol 1 for comparison.\r
769 s1 = self.dumps(x, 1)\r
770 self.assertIn(__name__, s1)\r
771 self.assertIn("MyList", s1)\r
772 self.assertEqual(opcode_in_pickle(opcode, s1), False)\r
773\r
774 y = self.loads(s1)\r
775 self.assertEqual(list(x), list(y))\r
776 self.assertEqual(x.__dict__, y.__dict__)\r
777\r
778 # Dump using protocol 2 for test.\r
779 s2 = self.dumps(x, 2)\r
780 self.assertNotIn(__name__, s2)\r
781 self.assertNotIn("MyList", s2)\r
782 self.assertEqual(opcode_in_pickle(opcode, s2), True)\r
783\r
784 y = self.loads(s2)\r
785 self.assertEqual(list(x), list(y))\r
786 self.assertEqual(x.__dict__, y.__dict__)\r
787\r
788 finally:\r
789 e.restore()\r
790\r
791 def test_global_ext1(self):\r
792 self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code\r
793 self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code\r
794\r
795 def test_global_ext2(self):\r
796 self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code\r
797 self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code\r
798 self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness\r
799\r
800 def test_global_ext4(self):\r
801 self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code\r
802 self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code\r
803 self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness\r
804\r
805 def test_list_chunking(self):\r
806 n = 10 # too small to chunk\r
807 x = range(n)\r
808 for proto in protocols:\r
809 s = self.dumps(x, proto)\r
810 y = self.loads(s)\r
811 self.assertEqual(x, y)\r
812 num_appends = count_opcode(pickle.APPENDS, s)\r
813 self.assertEqual(num_appends, proto > 0)\r
814\r
815 n = 2500 # expect at least two chunks when proto > 0\r
816 x = range(n)\r
817 for proto in protocols:\r
818 s = self.dumps(x, proto)\r
819 y = self.loads(s)\r
820 self.assertEqual(x, y)\r
821 num_appends = count_opcode(pickle.APPENDS, s)\r
822 if proto == 0:\r
823 self.assertEqual(num_appends, 0)\r
824 else:\r
825 self.assertTrue(num_appends >= 2)\r
826\r
827 def test_dict_chunking(self):\r
828 n = 10 # too small to chunk\r
829 x = dict.fromkeys(range(n))\r
830 for proto in protocols:\r
831 s = self.dumps(x, proto)\r
832 y = self.loads(s)\r
833 self.assertEqual(x, y)\r
834 num_setitems = count_opcode(pickle.SETITEMS, s)\r
835 self.assertEqual(num_setitems, proto > 0)\r
836\r
837 n = 2500 # expect at least two chunks when proto > 0\r
838 x = dict.fromkeys(range(n))\r
839 for proto in protocols:\r
840 s = self.dumps(x, proto)\r
841 y = self.loads(s)\r
842 self.assertEqual(x, y)\r
843 num_setitems = count_opcode(pickle.SETITEMS, s)\r
844 if proto == 0:\r
845 self.assertEqual(num_setitems, 0)\r
846 else:\r
847 self.assertTrue(num_setitems >= 2)\r
848\r
849 def test_simple_newobj(self):\r
850 x = object.__new__(SimpleNewObj) # avoid __init__\r
851 x.abc = 666\r
852 for proto in protocols:\r
853 s = self.dumps(x, proto)\r
854 self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), proto >= 2)\r
855 y = self.loads(s) # will raise TypeError if __init__ called\r
856 self.assertEqual(y.abc, 666)\r
857 self.assertEqual(x.__dict__, y.__dict__)\r
858\r
859 def test_newobj_list_slots(self):\r
860 x = SlotList([1, 2, 3])\r
861 x.foo = 42\r
862 x.bar = "hello"\r
863 s = self.dumps(x, 2)\r
864 y = self.loads(s)\r
865 self.assertEqual(list(x), list(y))\r
866 self.assertEqual(x.__dict__, y.__dict__)\r
867 self.assertEqual(x.foo, y.foo)\r
868 self.assertEqual(x.bar, y.bar)\r
869\r
870 def test_reduce_overrides_default_reduce_ex(self):\r
871 for proto in protocols:\r
872 x = REX_one()\r
873 self.assertEqual(x._reduce_called, 0)\r
874 s = self.dumps(x, proto)\r
875 self.assertEqual(x._reduce_called, 1)\r
876 y = self.loads(s)\r
877 self.assertEqual(y._reduce_called, 0)\r
878\r
879 def test_reduce_ex_called(self):\r
880 for proto in protocols:\r
881 x = REX_two()\r
882 self.assertEqual(x._proto, None)\r
883 s = self.dumps(x, proto)\r
884 self.assertEqual(x._proto, proto)\r
885 y = self.loads(s)\r
886 self.assertEqual(y._proto, None)\r
887\r
888 def test_reduce_ex_overrides_reduce(self):\r
889 for proto in protocols:\r
890 x = REX_three()\r
891 self.assertEqual(x._proto, None)\r
892 s = self.dumps(x, proto)\r
893 self.assertEqual(x._proto, proto)\r
894 y = self.loads(s)\r
895 self.assertEqual(y._proto, None)\r
896\r
897 def test_reduce_ex_calls_base(self):\r
898 for proto in protocols:\r
899 x = REX_four()\r
900 self.assertEqual(x._proto, None)\r
901 s = self.dumps(x, proto)\r
902 self.assertEqual(x._proto, proto)\r
903 y = self.loads(s)\r
904 self.assertEqual(y._proto, proto)\r
905\r
906 def test_reduce_calls_base(self):\r
907 for proto in protocols:\r
908 x = REX_five()\r
909 self.assertEqual(x._reduce_called, 0)\r
910 s = self.dumps(x, proto)\r
911 self.assertEqual(x._reduce_called, 1)\r
912 y = self.loads(s)\r
913 self.assertEqual(y._reduce_called, 1)\r
914\r
915 def test_reduce_bad_iterator(self):\r
916 # Issue4176: crash when 4th and 5th items of __reduce__()\r
917 # are not iterators\r
918 class C(object):\r
919 def __reduce__(self):\r
920 # 4th item is not an iterator\r
921 return list, (), None, [], None\r
922 class D(object):\r
923 def __reduce__(self):\r
924 # 5th item is not an iterator\r
925 return dict, (), None, None, []\r
926\r
927 # Protocol 0 is less strict and also accept iterables.\r
928 for proto in protocols:\r
929 try:\r
930 self.dumps(C(), proto)\r
931 except (AttributeError, pickle.PickleError, cPickle.PickleError):\r
932 pass\r
933 try:\r
934 self.dumps(D(), proto)\r
935 except (AttributeError, pickle.PickleError, cPickle.PickleError):\r
936 pass\r
937\r
938 def test_many_puts_and_gets(self):\r
939 # Test that internal data structures correctly deal with lots of\r
940 # puts/gets.\r
941 keys = ("aaa" + str(i) for i in xrange(100))\r
942 large_dict = dict((k, [4, 5, 6]) for k in keys)\r
943 obj = [dict(large_dict), dict(large_dict), dict(large_dict)]\r
944\r
945 for proto in protocols:\r
946 dumped = self.dumps(obj, proto)\r
947 loaded = self.loads(dumped)\r
948 self.assertEqual(loaded, obj,\r
949 "Failed protocol %d: %r != %r"\r
950 % (proto, obj, loaded))\r
951\r
952 def test_attribute_name_interning(self):\r
953 # Test that attribute names of pickled objects are interned when\r
954 # unpickling.\r
955 for proto in protocols:\r
956 x = C()\r
957 x.foo = 42\r
958 x.bar = "hello"\r
959 s = self.dumps(x, proto)\r
960 y = self.loads(s)\r
961 x_keys = sorted(x.__dict__)\r
962 y_keys = sorted(y.__dict__)\r
963 for x_key, y_key in zip(x_keys, y_keys):\r
964 self.assertIs(x_key, y_key)\r
965\r
966\r
967# Test classes for reduce_ex\r
968\r
969class REX_one(object):\r
970 _reduce_called = 0\r
971 def __reduce__(self):\r
972 self._reduce_called = 1\r
973 return REX_one, ()\r
974 # No __reduce_ex__ here, but inheriting it from object\r
975\r
976class REX_two(object):\r
977 _proto = None\r
978 def __reduce_ex__(self, proto):\r
979 self._proto = proto\r
980 return REX_two, ()\r
981 # No __reduce__ here, but inheriting it from object\r
982\r
983class REX_three(object):\r
984 _proto = None\r
985 def __reduce_ex__(self, proto):\r
986 self._proto = proto\r
987 return REX_two, ()\r
988 def __reduce__(self):\r
989 raise TestFailed, "This __reduce__ shouldn't be called"\r
990\r
991class REX_four(object):\r
992 _proto = None\r
993 def __reduce_ex__(self, proto):\r
994 self._proto = proto\r
995 return object.__reduce_ex__(self, proto)\r
996 # Calling base class method should succeed\r
997\r
998class REX_five(object):\r
999 _reduce_called = 0\r
1000 def __reduce__(self):\r
1001 self._reduce_called = 1\r
1002 return object.__reduce__(self)\r
1003 # This one used to fail with infinite recursion\r
1004\r
1005# Test classes for newobj\r
1006\r
1007class MyInt(int):\r
1008 sample = 1\r
1009\r
1010class MyLong(long):\r
1011 sample = 1L\r
1012\r
1013class MyFloat(float):\r
1014 sample = 1.0\r
1015\r
1016class MyComplex(complex):\r
1017 sample = 1.0 + 0.0j\r
1018\r
1019class MyStr(str):\r
1020 sample = "hello"\r
1021\r
1022class MyUnicode(unicode):\r
1023 sample = u"hello \u1234"\r
1024\r
1025class MyTuple(tuple):\r
1026 sample = (1, 2, 3)\r
1027\r
1028class MyList(list):\r
1029 sample = [1, 2, 3]\r
1030\r
1031class MyDict(dict):\r
1032 sample = {"a": 1, "b": 2}\r
1033\r
1034myclasses = [MyInt, MyLong, MyFloat,\r
1035 MyComplex,\r
1036 MyStr, MyUnicode,\r
1037 MyTuple, MyList, MyDict]\r
1038\r
1039\r
1040class SlotList(MyList):\r
1041 __slots__ = ["foo"]\r
1042\r
1043class SimpleNewObj(object):\r
1044 def __init__(self, a, b, c):\r
1045 # raise an error, to make sure this isn't called\r
1046 raise TypeError("SimpleNewObj.__init__() didn't expect to get called")\r
1047\r
1048class AbstractPickleModuleTests(unittest.TestCase):\r
1049\r
1050 def test_dump_closed_file(self):\r
1051 import os\r
1052 f = open(TESTFN, "w")\r
1053 try:\r
1054 f.close()\r
1055 self.assertRaises(ValueError, self.module.dump, 123, f)\r
1056 finally:\r
1057 os.remove(TESTFN)\r
1058\r
1059 def test_load_closed_file(self):\r
1060 import os\r
1061 f = open(TESTFN, "w")\r
1062 try:\r
1063 f.close()\r
1064 self.assertRaises(ValueError, self.module.dump, 123, f)\r
1065 finally:\r
1066 os.remove(TESTFN)\r
1067\r
1068 def test_load_from_and_dump_to_file(self):\r
1069 stream = cStringIO.StringIO()\r
1070 data = [123, {}, 124]\r
1071 self.module.dump(data, stream)\r
1072 stream.seek(0)\r
1073 unpickled = self.module.load(stream)\r
1074 self.assertEqual(unpickled, data)\r
1075\r
1076 def test_highest_protocol(self):\r
1077 # Of course this needs to be changed when HIGHEST_PROTOCOL changes.\r
1078 self.assertEqual(self.module.HIGHEST_PROTOCOL, 2)\r
1079\r
1080 def test_callapi(self):\r
1081 f = cStringIO.StringIO()\r
1082 # With and without keyword arguments\r
1083 self.module.dump(123, f, -1)\r
1084 self.module.dump(123, file=f, protocol=-1)\r
1085 self.module.dumps(123, -1)\r
1086 self.module.dumps(123, protocol=-1)\r
1087 self.module.Pickler(f, -1)\r
1088 self.module.Pickler(f, protocol=-1)\r
1089\r
1090 def test_incomplete_input(self):\r
1091 s = StringIO.StringIO("X''.")\r
1092 self.assertRaises(EOFError, self.module.load, s)\r
1093\r
1094 def test_restricted(self):\r
1095 # issue7128: cPickle failed in restricted mode\r
1096 builtins = {self.module.__name__: self.module,\r
1097 '__import__': __import__}\r
1098 d = {}\r
1099 teststr = "def f(): {0}.dumps(0)".format(self.module.__name__)\r
1100 exec teststr in {'__builtins__': builtins}, d\r
1101 d['f']()\r
1102\r
1103 def test_bad_input(self):\r
1104 # Test issue4298\r
1105 s = '\x58\0\0\0\x54'\r
1106 self.assertRaises(EOFError, self.module.loads, s)\r
1107 # Test issue7455\r
1108 s = '0'\r
1109 # XXX Why doesn't pickle raise UnpicklingError?\r
1110 self.assertRaises((IndexError, cPickle.UnpicklingError),\r
1111 self.module.loads, s)\r
1112\r
1113class AbstractPersistentPicklerTests(unittest.TestCase):\r
1114\r
1115 # This class defines persistent_id() and persistent_load()\r
1116 # functions that should be used by the pickler. All even integers\r
1117 # are pickled using persistent ids.\r
1118\r
1119 def persistent_id(self, object):\r
1120 if isinstance(object, int) and object % 2 == 0:\r
1121 self.id_count += 1\r
1122 return str(object)\r
1123 else:\r
1124 return None\r
1125\r
1126 def persistent_load(self, oid):\r
1127 self.load_count += 1\r
1128 object = int(oid)\r
1129 assert object % 2 == 0\r
1130 return object\r
1131\r
1132 def test_persistence(self):\r
1133 self.id_count = 0\r
1134 self.load_count = 0\r
1135 L = range(10)\r
1136 self.assertEqual(self.loads(self.dumps(L)), L)\r
1137 self.assertEqual(self.id_count, 5)\r
1138 self.assertEqual(self.load_count, 5)\r
1139\r
1140 def test_bin_persistence(self):\r
1141 self.id_count = 0\r
1142 self.load_count = 0\r
1143 L = range(10)\r
1144 self.assertEqual(self.loads(self.dumps(L, 1)), L)\r
1145 self.assertEqual(self.id_count, 5)\r
1146 self.assertEqual(self.load_count, 5)\r
1147\r
1148class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):\r
1149\r
1150 pickler_class = None\r
1151 unpickler_class = None\r
1152\r
1153 def setUp(self):\r
1154 assert self.pickler_class\r
1155 assert self.unpickler_class\r
1156\r
1157 def test_clear_pickler_memo(self):\r
1158 # To test whether clear_memo() has any effect, we pickle an object,\r
1159 # then pickle it again without clearing the memo; the two serialized\r
1160 # forms should be different. If we clear_memo() and then pickle the\r
1161 # object again, the third serialized form should be identical to the\r
1162 # first one we obtained.\r
1163 data = ["abcdefg", "abcdefg", 44]\r
1164 f = cStringIO.StringIO()\r
1165 pickler = self.pickler_class(f)\r
1166\r
1167 pickler.dump(data)\r
1168 first_pickled = f.getvalue()\r
1169\r
1170 # Reset StringIO object.\r
1171 f.seek(0)\r
1172 f.truncate()\r
1173\r
1174 pickler.dump(data)\r
1175 second_pickled = f.getvalue()\r
1176\r
1177 # Reset the Pickler and StringIO objects.\r
1178 pickler.clear_memo()\r
1179 f.seek(0)\r
1180 f.truncate()\r
1181\r
1182 pickler.dump(data)\r
1183 third_pickled = f.getvalue()\r
1184\r
1185 self.assertNotEqual(first_pickled, second_pickled)\r
1186 self.assertEqual(first_pickled, third_pickled)\r
1187\r
1188 def test_priming_pickler_memo(self):\r
1189 # Verify that we can set the Pickler's memo attribute.\r
1190 data = ["abcdefg", "abcdefg", 44]\r
1191 f = cStringIO.StringIO()\r
1192 pickler = self.pickler_class(f)\r
1193\r
1194 pickler.dump(data)\r
1195 first_pickled = f.getvalue()\r
1196\r
1197 f = cStringIO.StringIO()\r
1198 primed = self.pickler_class(f)\r
1199 primed.memo = pickler.memo\r
1200\r
1201 primed.dump(data)\r
1202 primed_pickled = f.getvalue()\r
1203\r
1204 self.assertNotEqual(first_pickled, primed_pickled)\r
1205\r
1206 def test_priming_unpickler_memo(self):\r
1207 # Verify that we can set the Unpickler's memo attribute.\r
1208 data = ["abcdefg", "abcdefg", 44]\r
1209 f = cStringIO.StringIO()\r
1210 pickler = self.pickler_class(f)\r
1211\r
1212 pickler.dump(data)\r
1213 first_pickled = f.getvalue()\r
1214\r
1215 f = cStringIO.StringIO()\r
1216 primed = self.pickler_class(f)\r
1217 primed.memo = pickler.memo\r
1218\r
1219 primed.dump(data)\r
1220 primed_pickled = f.getvalue()\r
1221\r
1222 unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled))\r
1223 unpickled_data1 = unpickler.load()\r
1224\r
1225 self.assertEqual(unpickled_data1, data)\r
1226\r
1227 primed = self.unpickler_class(cStringIO.StringIO(primed_pickled))\r
1228 primed.memo = unpickler.memo\r
1229 unpickled_data2 = primed.load()\r
1230\r
1231 primed.memo.clear()\r
1232\r
1233 self.assertEqual(unpickled_data2, data)\r
1234 self.assertTrue(unpickled_data2 is unpickled_data1)\r
1235\r
1236 def test_reusing_unpickler_objects(self):\r
1237 data1 = ["abcdefg", "abcdefg", 44]\r
1238 f = cStringIO.StringIO()\r
1239 pickler = self.pickler_class(f)\r
1240 pickler.dump(data1)\r
1241 pickled1 = f.getvalue()\r
1242\r
1243 data2 = ["abcdefg", 44, 44]\r
1244 f = cStringIO.StringIO()\r
1245 pickler = self.pickler_class(f)\r
1246 pickler.dump(data2)\r
1247 pickled2 = f.getvalue()\r
1248\r
1249 f = cStringIO.StringIO()\r
1250 f.write(pickled1)\r
1251 f.seek(0)\r
1252 unpickler = self.unpickler_class(f)\r
1253 self.assertEqual(unpickler.load(), data1)\r
1254\r
1255 f.seek(0)\r
1256 f.truncate()\r
1257 f.write(pickled2)\r
1258 f.seek(0)\r
1259 self.assertEqual(unpickler.load(), data2)\r