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