blob: 2a4357d7244c915e7463b79f780bd7245ca17c7b [file] [log] [blame]
Guido van Rossumb72cf2d1997-04-09 17:32:51 +00001# $Id$
2#
3# Copyright
4#
5# Copyright 1996 Digital Creations, L.C., 910 Princess Anne
6# Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
7# rights reserved. Copyright in this software is owned by DCLC,
8# unless otherwise indicated. Permission to use, copy and
9# distribute this software is hereby granted, provided that the
10# above copyright notice appear in all copies and that both that
11# copyright notice and this permission notice appear. Note that
12# any product, process or technology described in this software
13# may be the subject of other Intellectual Property rights
14# reserved by Digital Creations, L.C. and are not licensed
15# hereunder.
16#
17# Trademarks
18#
19# Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
20# All other trademarks are owned by their respective companies.
21#
22# No Warranty
23#
24# The software is provided "as is" without warranty of any kind,
25# either express or implied, including, but not limited to, the
26# implied warranties of merchantability, fitness for a particular
27# purpose, or non-infringement. This software could include
28# technical inaccuracies or typographical errors. Changes are
29# periodically made to the software; these changes will be
30# incorporated in new editions of the software. DCLC may make
31# improvements and/or changes in this software at any time
32# without notice.
33#
34# Limitation Of Liability
35#
36# In no event will DCLC be liable for direct, indirect, special,
37# incidental, economic, cover, or consequential damages arising
38# out of the use of or inability to use this software even if
39# advised of the possibility of such damages. Some states do not
40# allow the exclusion or limitation of implied warranties or
41# limitation of liability for incidental or consequential
42# damages, so the above limitation or exclusion may not apply to
43# you.
44#
45#
46# If you have questions regarding this software,
47# contact:
48#
49# Jim Fulton, jim@digicool.com
50#
51# (540) 371-6909
52#
53
Guido van Rossuma48061a1995-01-10 00:31:14 +000054"""\
55Pickling Algorithm
56------------------
57
58This module implements a basic but powerful algorithm for "pickling" (a.k.a.
59serializing, marshalling or flattening) nearly arbitrary Python objects.
60This is a more primitive notion than persistency -- although pickle
61reads and writes file objects, it does not handle the issue of naming
62persistent objects, nor the (even more complicated) area of concurrent
63access to persistent objects. The pickle module can transform a complex
64object into a byte stream and it can transform the byte stream into
65an object with the same internal structure. The most obvious thing to
66do with these byte streams is to write them onto a file, but it is also
67conceivable to send them across a network or store them in a database.
68
69Unlike the built-in marshal module, pickle handles the following correctly:
70
71- recursive objects
72- pointer sharing
Guido van Rossum0c891ce1995-03-14 15:09:05 +000073- classes and class instances
Guido van Rossuma48061a1995-01-10 00:31:14 +000074
75Pickle is Python-specific. This has the advantage that there are no
76restrictions imposed by external standards such as CORBA (which probably
77can't represent pointer sharing or recursive objects); however it means
78that non-Python programs may not be able to reconstruct pickled Python
79objects.
80
81Pickle uses a printable ASCII representation. This is slightly more
82voluminous than a binary representation. However, small integers actually
83take *less* space when represented as minimal-size decimal strings than
84when represented as 32-bit binary numbers, and strings are only much longer
85if they contain control characters or 8-bit characters. The big advantage
86of using printable ASCII (and of some other characteristics of pickle's
87representation) is that for debugging or recovery purposes it is possible
88for a human to read the pickled file with a standard text editor. (I could
89have gone a step further and used a notation like S-expressions, but the
90parser would have been considerably more complicated and slower, and the
91files would probably have become much larger.)
92
93Pickle doesn't handle code objects, which marshal does.
94I suppose pickle could, and maybe it should, but there's probably no
95great need for it right now (as long as marshal continues to be used
96for reading and writing code objects), and at least this avoids
97the possibility of smuggling Trojan horses into a program.
98
99For the benefit of persistency modules written using pickle, it supports
100the notion of a reference to an object outside the pickled data stream.
101Such objects are referenced by a name, which is an arbitrary string of
102printable ASCII characters. The resolution of such names is not defined
103by the pickle module -- the persistent object module will have to implement
104a method "persistent_load". To write references to persistent objects,
105the persistent module must define a method "persistent_id" which returns
106either None or the persistent ID of the object.
107
108There are some restrictions on the pickling of class instances.
109
110First of all, the class must be defined at the top level in a module.
111
Guido van Rossum37a6f161996-08-08 18:35:22 +0000112Next, it must normally be possible to create class instances by
113calling the class without arguments. Usually, this is best
114accomplished by providing default values for all arguments to its
115__init__ method (if it has one). If this is undesirable, the
116class can define a method __getinitargs__, which should return a
117*tuple* containing the arguments to be passed to the class
Guido van Rossuma48061a1995-01-10 00:31:14 +0000118constructor.
119
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000120Classes can influence how their instances are pickled -- if the class defines
Guido van Rossuma48061a1995-01-10 00:31:14 +0000121the method __getstate__, it is called and the return state is pickled
122as the contents for the instance, and if the class defines the
123method __setstate__, it is called with the unpickled state. (Note
124that these methods can also be used to implement copying class instances.)
125If there is no __getstate__ method, the instance's __dict__
126is pickled. If there is no __setstate__ method, the pickled object
127must be a dictionary and its items are assigned to the new instance's
128dictionary. (If a class defines both __getstate__ and __setstate__,
129the state object needn't be a dictionary -- these methods can do what they
130want.)
131
132Note that when class instances are pickled, their class's code and data
133is not pickled along with them. Only the instance data is pickled.
134This is done on purpose, so you can fix bugs in a class or add methods and
135still load objects that were created with an earlier version of the
136class. If you plan to have long-lived objects that will see many versions
137of a class, it may be worth to put a version number in the objects so
138that suitable conversions can be made by the class's __setstate__ method.
139
140The interface is as follows:
141
Guido van Rossum256cbd71995-02-16 16:30:50 +0000142To pickle an object x onto a file f, open for writing:
Guido van Rossuma48061a1995-01-10 00:31:14 +0000143
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000144 p = pickle.Pickler(f)
145 p.dump(x)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000146
147To unpickle an object x from a file f, open for reading:
148
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000149 u = pickle.Unpickler(f)
150 x = u.load()
Guido van Rossuma48061a1995-01-10 00:31:14 +0000151
152The Pickler class only calls the method f.write with a string argument
153(XXX possibly the interface should pass f.write instead of f).
154The Unpickler calls the methods f.read(with an integer argument)
155and f.readline(without argument), both returning a string.
156It is explicitly allowed to pass non-file objects here, as long as they
157have the right methods.
158
159The following types can be pickled:
160
161- None
162- integers, long integers, floating point numbers
163- strings
Guido van Rossum256cbd71995-02-16 16:30:50 +0000164- tuples, lists and dictionaries containing only picklable objects
Guido van Rossuma48061a1995-01-10 00:31:14 +0000165- class instances whose __dict__ or __setstate__() is picklable
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000166- classes
Guido van Rossuma48061a1995-01-10 00:31:14 +0000167
168Attempts to pickle unpicklable objects will raise an exception
169after having written an unspecified number of bytes to the file argument.
170
171It is possible to make multiple calls to Pickler.dump() or to
172Unpickler.load(), as long as there is a one-to-one correspondence
Guido van Rossum256cbd71995-02-16 16:30:50 +0000173between pickler and Unpickler objects and between dump and load calls
Guido van Rossuma48061a1995-01-10 00:31:14 +0000174for any pair of corresponding Pickler and Unpicklers. WARNING: this
175is intended for pickleing multiple objects without intervening modifications
176to the objects or their parts. If you modify an object and then pickle
177it again using the same Pickler instance, the object is not pickled
178again -- a reference to it is pickled and the Unpickler will return
179the old value, not the modified one. (XXX There are two problems here:
180(a) detecting changes, and (b) marshalling a minimal set of changes.
181I have no answers. Garbage Collection may also become a problem here.)
182"""
183
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000184__version__ = "1.7" # Code version
Guido van Rossuma48061a1995-01-10 00:31:14 +0000185
186from types import *
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000187from copy_reg import *
188import string, marshal
Guido van Rossuma48061a1995-01-10 00:31:14 +0000189
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000190format_version = "1.2" # File format version we write
191compatible_formats = ["1.0", "1.1"] # Old format versions we can read
192
193mdumps = marshal.dumps
194mloads = marshal.loads
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000195
Guido van Rossum7849da81995-03-09 14:08:35 +0000196PicklingError = "pickle.PicklingError"
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000197UnpicklingError = "pickle.UnpicklingError"
Guido van Rossum7849da81995-03-09 14:08:35 +0000198
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000199MARK = '('
200STOP = '.'
201POP = '0'
202POP_MARK = '1'
203DUP = '2'
204FLOAT = 'F'
205INT = 'I'
206BININT = 'J'
207BININT1 = 'K'
208LONG = 'L'
209BININT2 = 'M'
210NONE = 'N'
211PERSID = 'P'
212BINPERSID = 'Q'
213REDUCE = 'R'
214STRING = 'S'
215BINSTRING = 'T'
216SHORT_BINSTRING = 'U'
217APPEND = 'a'
218BUILD = 'b'
219GLOBAL = 'c'
220DICT = 'd'
221EMPTY_DICT = '}'
222APPENDS = 'e'
223GET = 'g'
224BINGET = 'h'
225INST = 'i'
226LONG_BINGET = 'j'
227LIST = 'l'
228EMPTY_LIST = ']'
229OBJ = 'o'
230PUT = 'p'
231BINPUT = 'q'
232LONG_BINPUT = 'r'
233SETITEM = 's'
234TUPLE = 't'
235EMPTY_TUPLE = ')'
236SETITEMS = 'u'
Guido van Rossuma48061a1995-01-10 00:31:14 +0000237
238class Pickler:
239
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000240 def __init__(self, file, bin = 0):
241 self.write = file.write
242 self.memo = {}
243 self.bin = bin
Guido van Rossuma48061a1995-01-10 00:31:14 +0000244
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000245 def dump(self, object):
246 self.save(object)
247 self.write(STOP)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000248
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000249 def dump_special(self, callable, args, state = None):
250 if (type(args) is not TupleType):
251 raise PicklingError, "Second argument to dump_special " \
252 "must be a tuple"
Guido van Rossuma48061a1995-01-10 00:31:14 +0000253
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000254 self.save_reduce(callable, args, state)
255 self.write(STOP)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000256
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000257 def put(self, i):
258 if (self.bin):
259 s = mdumps(i)[1:]
260 if (i < 256):
261 return BINPUT + s[0]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000262
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000263 return LONG_BINPUT + s
Guido van Rossuma48061a1995-01-10 00:31:14 +0000264
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000265 return PUT + `i` + '\n'
Guido van Rossuma48061a1995-01-10 00:31:14 +0000266
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000267 def get(self, i):
268 if (self.bin):
269 s = mdumps(i)[1:]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000270
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000271 if (i < 256):
272 return BINGET + s[0]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000273
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000274 return LONG_BINGET + s
Guido van Rossuma48061a1995-01-10 00:31:14 +0000275
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000276 return GET + `i` + '\n'
277
278 def save(self, object, pers_save = 0):
279 memo = self.memo
Guido van Rossuma48061a1995-01-10 00:31:14 +0000280
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000281 if (not pers_save):
282 pid = self.persistent_id(object)
283 if (pid is not None):
284 self.save_pers(pid)
285 return
Guido van Rossuma48061a1995-01-10 00:31:14 +0000286
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000287 d = id(object)
288
289 t = type(object)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000290
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000291 if ((t is TupleType) and (len(object) == 0)):
292 if (self.bin):
293 self.save_empty_tuple(object)
294 else:
295 self.save_tuple(object)
296 return
Guido van Rossuma48061a1995-01-10 00:31:14 +0000297
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000298 if memo.has_key(d):
299 self.write(self.get(memo[d][0]))
300 return
301
302 try:
303 f = self.dispatch[t]
304 except KeyError:
305 pid = self.inst_persistent_id(object)
306 if pid is not None:
307 self.save_pers(pid)
308 return
309
310 try:
311 reduce = dispatch_table[t]
312 except KeyError:
313 try:
314 reduce = object.__reduce__
315 except AttributeError:
316 raise PicklingError, \
317 "can't pickle %s objects" % `t.__name__`
318 else:
319 tup = reduce()
320 else:
321 tup = reduce(object)
322
323 if (type(tup) is not TupleType):
324 raise PicklingError, "Value returned by %s must be a " \
325 "tuple" % reduce
326
327 l = len(tup)
328
329 if ((l != 2) and (l != 3)):
330 raise PicklingError, "tuple returned by %s must contain " \
331 "only two or three elements" % reduce
332
333 callable = tup[0]
334 arg_tup = tup[1]
335
336 if (l > 2):
337 state = tup[2]
338 else:
339 state = None
340
341 if (type(arg_tup) is not TupleType):
342 raise PicklingError, "Second element of tuple returned " \
343 "by %s must be a tuple" % reduce
344
345 self.save_reduce(callable, arg_tup, state)
346 return
347
348 f(self, object)
349
350 def persistent_id(self, object):
351 return None
352
353 def inst_persistent_id(self, object):
354 return None
355
356 def save_pers(self, pid):
357 if (not self.bin):
358 self.write(PERSID + str(pid) + '\n')
359 else:
360 self.save(pid, 1)
361 self.write(BINPERSID)
362
363 def save_reduce(self, callable, arg_tup, state = None):
364 write = self.write
365 save = self.save
366
367 save(callable)
368 save(arg_tup)
369 write(REDUCE)
370
371 if (state is not None):
372 save(state)
373 write(BUILD)
374
375 dispatch = {}
376
377 def save_none(self, object):
378 self.write(NONE)
379 dispatch[NoneType] = save_none
380
381 def save_int(self, object):
382 if (self.bin):
383 i = mdumps(object)[1:]
384 if (i[-2:] == '\000\000'):
385 if (i[-3] == '\000'):
386 self.write(BININT1 + i[:-3])
387 return
388
389 self.write(BININT2 + i[:-2])
390 return
391
392 self.write(BININT + i)
393 else:
394 self.write(INT + `object` + '\n')
395 dispatch[IntType] = save_int
396
397 def save_long(self, object):
398 self.write(LONG + `object` + '\n')
399 dispatch[LongType] = save_long
400
401 def save_float(self, object):
402 self.write(FLOAT + `object` + '\n')
403 dispatch[FloatType] = save_float
404
405 def save_string(self, object):
406 d = id(object)
407 memo = self.memo
408
409 if (self.bin):
410 l = len(object)
411 s = mdumps(l)[1:]
412 if (l < 256):
413 self.write(SHORT_BINSTRING + s[0] + object)
414 else:
415 self.write(BINSTRING + s + object)
416 else:
417 self.write(STRING + `object` + '\n')
418
419 memo_len = len(memo)
420 self.write(self.put(memo_len))
421 memo[d] = (memo_len, object)
422 dispatch[StringType] = save_string
423
424 def save_tuple(self, object):
425
426 write = self.write
427 save = self.save
428 memo = self.memo
429
430 d = id(object)
431
432 write(MARK)
433
434 for element in object:
435 save(element)
436
437 if (len(object) and memo.has_key(d)):
438 if (self.bin):
439 write(POP_MARK + self.get(memo[d][0]))
440 return
441
442 write(POP * (len(object) + 1) + self.get(mem[d][0]))
443 return
444
445 memo_len = len(memo)
446 self.write(TUPLE + self.put(memo_len))
447 memo[d] = (memo_len, object)
448 dispatch[TupleType] = save_tuple
449
450 def save_empty_tuple(self, object):
451 self.write(EMPTY_TUPLE)
452
453 def save_list(self, object):
454 d = id(object)
455
456 write = self.write
457 save = self.save
458 memo = self.memo
459
460 if (self.bin):
461 write(EMPTY_LIST)
462 else:
463 write(MARK + LIST)
464
465 memo_len = len(memo)
466 write(self.put(memo_len))
467 memo[d] = (memo_len, object)
468
469 using_appends = (self.bin and (len(object) > 1))
470
471 if (using_appends):
472 write(MARK)
473
474 for element in object:
475 save(element)
476
477 if (not using_appends):
478 write(APPEND)
479
480 if (using_appends):
481 write(APPENDS)
482 dispatch[ListType] = save_list
483
484 def save_dict(self, object):
485 d = id(object)
486
487 write = self.write
488 save = self.save
489 memo = self.memo
490
491 if (self.bin):
492 write(EMPTY_DICT)
493 else:
494 write(MARK + DICT)
495
496 memo_len = len(memo)
497 self.write(self.put(memo_len))
498 memo[d] = (memo_len, object)
499
500 using_setitems = (self.bin and (len(object) > 1))
501
502 if (using_setitems):
503 write(MARK)
504
505 items = object.items()
506 for key, value in items:
507 save(key)
508 save(value)
509
510 if (not using_setitems):
511 write(SETITEM)
512
513 if (using_setitems):
514 write(SETITEMS)
515
516 dispatch[DictionaryType] = save_dict
517
518 def save_inst(self, object):
519 d = id(object)
520 cls = object.__class__
521
522 memo = self.memo
523 write = self.write
524 save = self.save
525
526 if hasattr(object, '__getinitargs__'):
527 args = object.__getinitargs__()
528 len(args) # XXX Assert it's a sequence
529 else:
530 args = ()
531
532 write(MARK)
533
534 if (self.bin):
535 save(cls)
536
537 for arg in args:
538 save(arg)
539
540 memo_len = len(memo)
541 if (self.bin):
542 write(OBJ + self.put(memo_len))
543 else:
544 module = whichmodule(cls, cls.__name__)
545 name = cls.__name__
546 write(INST + module + '\n' + name + '\n' +
547 self.put(memo_len))
548
549 memo[d] = (memo_len, object)
550
551 try:
552 getstate = object.__getstate__
553 except AttributeError:
554 stuff = object.__dict__
555 else:
556 stuff = getstate()
557 save(stuff)
558 write(BUILD)
559 dispatch[InstanceType] = save_inst
560
561 def save_global(self, object, name = None):
562 write = self.write
563 memo = self.memo
564
565 if (name is None):
566 name = object.__name__
567
568 module = whichmodule(object, name)
569
570 memo_len = len(memo)
571 write(GLOBAL + module + '\n' + name + '\n' +
572 self.put(memo_len))
573 memo[id(object)] = (memo_len, object)
574 dispatch[ClassType] = save_global
575 dispatch[FunctionType] = save_global
576 dispatch[BuiltinFunctionType] = save_global
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000577
Guido van Rossuma48061a1995-01-10 00:31:14 +0000578
579classmap = {}
580
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000581def whichmodule(cls, clsname):
582 """Figure out the module in which a class occurs.
Guido van Rossuma48061a1995-01-10 00:31:14 +0000583
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000584 Search sys.modules for the module.
585 Cache in classmap.
586 Return a module name.
587 If the class cannot be found, return __main__.
588 """
589 if classmap.has_key(cls):
590 return classmap[cls]
591 import sys
592
593 for name, module in sys.modules.items():
594 if hasattr(module, clsname) and \
595 getattr(module, clsname) is cls:
596 break
597 else:
598 name = '__main__'
599 classmap[cls] = name
600 return name
Guido van Rossuma48061a1995-01-10 00:31:14 +0000601
602
603class Unpickler:
604
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000605 def __init__(self, file):
606 self.readline = file.readline
607 self.read = file.read
608 self.memo = {}
Guido van Rossuma48061a1995-01-10 00:31:14 +0000609
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000610 def load(self):
611 self.mark = ['spam'] # Any new unique object
612 self.stack = []
613 self.append = self.stack.append
614 read = self.read
615 dispatch = self.dispatch
616 try:
617 while 1:
618 key = read(1)
619 dispatch[key](self)
620 except STOP, value:
621 return value
622
623 def marker(self):
624 stack = self.stack
625 mark = self.mark
626 k = len(stack)-1
627 while stack[k] is not mark: k = k-1
628 return k
629
630 dispatch = {}
631
632 def load_eof(self):
633 raise EOFError
634 dispatch[''] = load_eof
635
636 def load_persid(self):
637 pid = self.readline()[:-1]
638 self.append(self.persistent_load(pid))
639 dispatch[PERSID] = load_persid
640
641 def load_binpersid(self):
642 stack = self.stack
643
644 pid = stack[-1]
645 del stack[-1]
646
647 self.append(self.persistent_load(pid))
648 dispatch[BINPERSID] = load_binpersid
649
650 def load_none(self):
651 self.append(None)
652 dispatch[NONE] = load_none
653
654 def load_int(self):
655 self.append(string.atoi(self.readline()[:-1], 0))
656 dispatch[INT] = load_int
657
658 def load_binint(self):
659 self.append(mloads('i' + self.read(4)))
660 dispatch[BININT] = load_binint
661
662 def load_binint1(self):
663 self.append(mloads('i' + self.read(1) + '\000\000\000'))
664 dispatch[BININT1] = load_binint1
665
666 def load_binint2(self):
667 self.append(mloads('i' + self.read(2) + '\000\000'))
668 dispatch[BININT2] = load_binint2
669
670 def load_long(self):
671 self.append(string.atol(self.readline()[:-1], 0))
672 dispatch[LONG] = load_long
673
674 def load_float(self):
675 self.append(string.atof(self.readline()[:-1]))
676 dispatch[FLOAT] = load_float
677
678 def load_string(self):
679 self.append(eval(self.readline()[:-1],
680 {'__builtins__': {}})) # Let's be careful
681 dispatch[STRING] = load_string
682
683 def load_binstring(self):
684 len = mloads('i' + self.read(4))
685 self.append(self.read(len))
686 dispatch[BINSTRING] = load_binstring
687
688 def load_short_binstring(self):
689 len = mloads('i' + self.read(1) + '\000\000\000')
690 self.append(self.read(len))
691 dispatch[SHORT_BINSTRING] = load_short_binstring
692
693 def load_tuple(self):
694 k = self.marker()
695 self.stack[k:] = [tuple(self.stack[k+1:])]
696 dispatch[TUPLE] = load_tuple
697
698 def load_empty_tuple(self):
699 self.stack.append(())
700 dispatch[EMPTY_TUPLE] = load_empty_tuple
701
702 def load_empty_list(self):
703 self.stack.append([])
704 dispatch[EMPTY_LIST] = load_empty_list
705
706 def load_empty_dictionary(self):
707 self.stack.append({})
708 dispatch[EMPTY_DICT] = load_empty_dictionary
709
710 def load_list(self):
711 k = self.marker()
712 self.stack[k:] = [self.stack[k+1:]]
713 dispatch[LIST] = load_list
714
715 def load_dict(self):
716 k = self.marker()
717 d = {}
718 items = self.stack[k+1:]
719 for i in range(0, len(items), 2):
720 key = items[i]
721 value = items[i+1]
722 d[key] = value
723 self.stack[k:] = [d]
724 dispatch[DICT] = load_dict
725
726 def load_inst(self):
727 k = self.marker()
728 args = tuple(self.stack[k+1:])
729 del self.stack[k:]
730 module = self.readline()[:-1]
731 name = self.readline()[:-1]
732 klass = self.find_class(module, name)
733 if (type(klass) is not ClassType):
734 raise SystemError, "Imported object %s from module %s is " \
735 "not a class" % (name, module)
736
737 value = apply(klass, args)
738 self.append(value)
739 dispatch[INST] = load_inst
740
741 def load_obj(self):
742 stack = self.stack
743 k = self.marker()
744 klass = stack[k + 1]
745 del stack[k + 1]
746 args = tuple(stack[k + 1:])
747 del stack[k:]
748 value = apply(klass, args)
749 self.append(value)
750 dispatch[OBJ] = load_obj
751
752 def load_global(self):
753 module = self.readline()[:-1]
754 name = self.readline()[:-1]
755 klass = self.find_class(module, name)
756 self.append(klass)
757 dispatch[GLOBAL] = load_global
758
759 def find_class(self, module, name):
760 env = {}
761
762 try:
763 exec 'from %s import %s' % (module, name) in env
764 except ImportError:
765 raise SystemError, \
766 "Failed to import class %s from module %s" % \
767 (name, module)
768 klass = env[name]
769 return klass
770
771 def load_reduce(self):
772 stack = self.stack
773
774 callable = stack[-2]
775 arg_tup = stack[-1]
776 del stack[-2:]
777
778 if (type(callable) is not ClassType):
779 if (not safe_constructors.has_key(callable)):
Guido van Rossuma48061a1995-01-10 00:31:14 +0000780 try:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000781 safe = callable.__safe_for_unpickling__
782 except AttributeError:
783 safe = None
Guido van Rossuma48061a1995-01-10 00:31:14 +0000784
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000785 if (not safe):
786 raise UnpicklingError, "%s is not safe for " \
787 "unpickling" % callable
Guido van Rossuma48061a1995-01-10 00:31:14 +0000788
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000789 value = apply(callable, arg_tup)
790 self.append(value)
791 dispatch[REDUCE] = load_reduce
Guido van Rossuma48061a1995-01-10 00:31:14 +0000792
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000793 def load_pop(self):
794 del self.stack[-1]
795 dispatch[POP] = load_pop
Guido van Rossum7b5430f1995-03-04 22:25:21 +0000796
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000797 def load_pop_mark(self):
798 k = self.marker()
799 del self.stack[k:]
800 dispatch[POP_MARK] = load_pop_mark
Guido van Rossuma48061a1995-01-10 00:31:14 +0000801
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000802 def load_dup(self):
803 self.append(stack[-1])
804 dispatch[DUP] = load_dup
Guido van Rossuma48061a1995-01-10 00:31:14 +0000805
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000806 def load_get(self):
807 self.append(self.memo[self.readline()[:-1]])
808 dispatch[GET] = load_get
Guido van Rossum78536471996-04-12 13:36:27 +0000809
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000810 def load_binget(self):
811 i = mloads('i' + self.read(1) + '\000\000\000')
812 self.append(self.memo[`i`])
813 dispatch[BINGET] = load_binget
Guido van Rossum78536471996-04-12 13:36:27 +0000814
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000815 def load_long_binget(self):
816 i = mloads('i' + self.read(4))
817 self.append(self.memo[`i`])
818 dispatch[LONG_BINGET] = load_long_binget
Guido van Rossum78536471996-04-12 13:36:27 +0000819
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000820 def load_put(self):
821 self.memo[self.readline()[:-1]] = self.stack[-1]
822 dispatch[PUT] = load_put
Guido van Rossuma48061a1995-01-10 00:31:14 +0000823
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000824 def load_binput(self):
825 i = mloads('i' + self.read(1) + '\000\000\000')
826 self.memo[`i`] = self.stack[-1]
827 dispatch[BINPUT] = load_binput
Guido van Rossuma48061a1995-01-10 00:31:14 +0000828
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000829 def load_long_binput(self):
830 i = mloads('i' + self.read(4))
831 self.memo[`i`] = self.stack[-1]
832 dispatch[LONG_BINPUT] = load_long_binput
Guido van Rossuma48061a1995-01-10 00:31:14 +0000833
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000834 def load_append(self):
835 stack = self.stack
836 value = stack[-1]
837 del stack[-1]
838 list = stack[-1]
839 list.append(value)
840 dispatch[APPEND] = load_append
Guido van Rossuma48061a1995-01-10 00:31:14 +0000841
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000842 def load_appends(self):
843 stack = self.stack
844 mark = self.marker()
845 list = stack[mark - 1]
846 for i in range(mark + 1, len(stack)):
847 list.append(stack[i])
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000848
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000849 del stack[mark:]
850 dispatch[APPENDS] = load_appends
851
852 def load_setitem(self):
853 stack = self.stack
854 value = stack[-1]
855 key = stack[-2]
856 del stack[-2:]
857 dict = stack[-1]
858 dict[key] = value
859 dispatch[SETITEM] = load_setitem
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000860
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000861 def load_setitems(self):
862 stack = self.stack
863 mark = self.marker()
864 dict = stack[mark - 1]
865 for i in range(mark + 1, len(stack), 2):
866 dict[stack[i]] = stack[i + 1]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000867
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000868 del stack[mark:]
869 dispatch[SETITEMS] = load_setitems
Guido van Rossuma48061a1995-01-10 00:31:14 +0000870
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000871 def load_build(self):
872 stack = self.stack
873 value = stack[-1]
874 del stack[-1]
875 inst = stack[-1]
876 try:
877 setstate = inst.__setstate__
878 except AttributeError:
879 for key in value.keys():
880 setattr(inst, key, value[key])
881 else:
882 setstate(value)
883 dispatch[BUILD] = load_build
Guido van Rossuma48061a1995-01-10 00:31:14 +0000884
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000885 def load_mark(self):
886 self.append(self.mark)
887 dispatch[MARK] = load_mark
Guido van Rossuma48061a1995-01-10 00:31:14 +0000888
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000889 def load_stop(self):
890 value = self.stack[-1]
891 del self.stack[-1]
892 raise STOP, value
893 dispatch[STOP] = load_stop
Guido van Rossuma48061a1995-01-10 00:31:14 +0000894
895
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000896# Shorthands
897
Guido van Rossumc7c5e691996-07-22 22:26:07 +0000898from StringIO import StringIO
899
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000900def dump(object, file, bin = 0):
901 Pickler(file, bin).dump(object)
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000902
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000903def dumps(object, bin = 0):
904 file = StringIO()
905 Pickler(file, bin).dump(object)
906 return file.getvalue()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000907
908def load(file):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000909 return Unpickler(file).load()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000910
911def loads(str):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000912 file = StringIO(str)
913 return Unpickler(file).load()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000914
915
916# The rest is used for testing only
917
Guido van Rossuma48061a1995-01-10 00:31:14 +0000918class C:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000919 def __cmp__(self, other):
920 return cmp(self.__dict__, other.__dict__)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000921
922def test():
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000923 fn = 'out'
924 c = C()
925 c.foo = 1
926 c.bar = 2
927 x = [0, 1, 2, 3]
928 y = ('abc', 'abc', c, c)
929 x.append(y)
930 x.append(y)
931 x.append(5)
932 f = open(fn, 'w')
933 F = Pickler(f)
934 F.dump(x)
935 f.close()
936 f = open(fn, 'r')
937 U = Unpickler(f)
938 x2 = U.load()
939 print x
940 print x2
941 print x == x2
942 print map(id, x)
943 print map(id, x2)
944 print F.memo
945 print U.memo
Guido van Rossuma48061a1995-01-10 00:31:14 +0000946
947if __name__ == '__main__':
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000948 test()