blob: 97eb4e45bc8def715cc7756f7cc22b78c04bd873 [file] [log] [blame]
Guido van Rossuma48061a1995-01-10 00:31:14 +00001"""\
2Pickling Algorithm
3------------------
4
5This module implements a basic but powerful algorithm for "pickling" (a.k.a.
6serializing, marshalling or flattening) nearly arbitrary Python objects.
7This is a more primitive notion than persistency -- although pickle
8reads and writes file objects, it does not handle the issue of naming
9persistent objects, nor the (even more complicated) area of concurrent
10access to persistent objects. The pickle module can transform a complex
11object into a byte stream and it can transform the byte stream into
12an object with the same internal structure. The most obvious thing to
13do with these byte streams is to write them onto a file, but it is also
14conceivable to send them across a network or store them in a database.
15
16Unlike the built-in marshal module, pickle handles the following correctly:
17
18- recursive objects
19- pointer sharing
Guido van Rossum0c891ce1995-03-14 15:09:05 +000020- classes and class instances
Guido van Rossuma48061a1995-01-10 00:31:14 +000021
22Pickle is Python-specific. This has the advantage that there are no
23restrictions imposed by external standards such as CORBA (which probably
24can't represent pointer sharing or recursive objects); however it means
25that non-Python programs may not be able to reconstruct pickled Python
26objects.
27
28Pickle uses a printable ASCII representation. This is slightly more
29voluminous than a binary representation. However, small integers actually
30take *less* space when represented as minimal-size decimal strings than
31when represented as 32-bit binary numbers, and strings are only much longer
32if they contain control characters or 8-bit characters. The big advantage
33of using printable ASCII (and of some other characteristics of pickle's
34representation) is that for debugging or recovery purposes it is possible
35for a human to read the pickled file with a standard text editor. (I could
36have gone a step further and used a notation like S-expressions, but the
37parser would have been considerably more complicated and slower, and the
38files would probably have become much larger.)
39
40Pickle doesn't handle code objects, which marshal does.
41I suppose pickle could, and maybe it should, but there's probably no
42great need for it right now (as long as marshal continues to be used
43for reading and writing code objects), and at least this avoids
44the possibility of smuggling Trojan horses into a program.
45
46For the benefit of persistency modules written using pickle, it supports
47the notion of a reference to an object outside the pickled data stream.
48Such objects are referenced by a name, which is an arbitrary string of
49printable ASCII characters. The resolution of such names is not defined
50by the pickle module -- the persistent object module will have to implement
51a method "persistent_load". To write references to persistent objects,
52the persistent module must define a method "persistent_id" which returns
53either None or the persistent ID of the object.
54
55There are some restrictions on the pickling of class instances.
56
57First of all, the class must be defined at the top level in a module.
58
Guido van Rossum37a6f161996-08-08 18:35:22 +000059Next, it must normally be possible to create class instances by
60calling the class without arguments. Usually, this is best
61accomplished by providing default values for all arguments to its
62__init__ method (if it has one). If this is undesirable, the
63class can define a method __getinitargs__, which should return a
64*tuple* containing the arguments to be passed to the class
Guido van Rossuma48061a1995-01-10 00:31:14 +000065constructor.
66
Guido van Rossum0c891ce1995-03-14 15:09:05 +000067Classes can influence how their instances are pickled -- if the class defines
Guido van Rossuma48061a1995-01-10 00:31:14 +000068the method __getstate__, it is called and the return state is pickled
69as the contents for the instance, and if the class defines the
70method __setstate__, it is called with the unpickled state. (Note
71that these methods can also be used to implement copying class instances.)
72If there is no __getstate__ method, the instance's __dict__
73is pickled. If there is no __setstate__ method, the pickled object
74must be a dictionary and its items are assigned to the new instance's
75dictionary. (If a class defines both __getstate__ and __setstate__,
76the state object needn't be a dictionary -- these methods can do what they
77want.)
78
79Note that when class instances are pickled, their class's code and data
80is not pickled along with them. Only the instance data is pickled.
81This is done on purpose, so you can fix bugs in a class or add methods and
82still load objects that were created with an earlier version of the
83class. If you plan to have long-lived objects that will see many versions
84of a class, it may be worth to put a version number in the objects so
85that suitable conversions can be made by the class's __setstate__ method.
86
87The interface is as follows:
88
Guido van Rossum256cbd71995-02-16 16:30:50 +000089To pickle an object x onto a file f, open for writing:
Guido van Rossuma48061a1995-01-10 00:31:14 +000090
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000091 p = pickle.Pickler(f)
92 p.dump(x)
Guido van Rossuma48061a1995-01-10 00:31:14 +000093
94To unpickle an object x from a file f, open for reading:
95
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000096 u = pickle.Unpickler(f)
97 x = u.load()
Guido van Rossuma48061a1995-01-10 00:31:14 +000098
99The Pickler class only calls the method f.write with a string argument
100(XXX possibly the interface should pass f.write instead of f).
101The Unpickler calls the methods f.read(with an integer argument)
102and f.readline(without argument), both returning a string.
103It is explicitly allowed to pass non-file objects here, as long as they
104have the right methods.
105
106The following types can be pickled:
107
108- None
109- integers, long integers, floating point numbers
110- strings
Guido van Rossum256cbd71995-02-16 16:30:50 +0000111- tuples, lists and dictionaries containing only picklable objects
Guido van Rossuma48061a1995-01-10 00:31:14 +0000112- class instances whose __dict__ or __setstate__() is picklable
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000113- classes
Guido van Rossuma48061a1995-01-10 00:31:14 +0000114
115Attempts to pickle unpicklable objects will raise an exception
116after having written an unspecified number of bytes to the file argument.
117
118It is possible to make multiple calls to Pickler.dump() or to
119Unpickler.load(), as long as there is a one-to-one correspondence
Guido van Rossum256cbd71995-02-16 16:30:50 +0000120between pickler and Unpickler objects and between dump and load calls
Guido van Rossuma48061a1995-01-10 00:31:14 +0000121for any pair of corresponding Pickler and Unpicklers. WARNING: this
122is intended for pickleing multiple objects without intervening modifications
123to the objects or their parts. If you modify an object and then pickle
124it again using the same Pickler instance, the object is not pickled
125again -- a reference to it is pickled and the Unpickler will return
126the old value, not the modified one. (XXX There are two problems here:
127(a) detecting changes, and (b) marshalling a minimal set of changes.
128I have no answers. Garbage Collection may also become a problem here.)
129"""
130
Guido van Rossum8be9a111997-04-25 19:52:29 +0000131__version__ = "1.8" # Code version
Guido van Rossuma48061a1995-01-10 00:31:14 +0000132
133from types import *
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000134from copy_reg import *
135import string, marshal
Guido van Rossuma48061a1995-01-10 00:31:14 +0000136
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000137format_version = "1.2" # File format version we write
138compatible_formats = ["1.0", "1.1"] # Old format versions we can read
139
140mdumps = marshal.dumps
141mloads = marshal.loads
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000142
Guido van Rossum7849da81995-03-09 14:08:35 +0000143PicklingError = "pickle.PicklingError"
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000144UnpicklingError = "pickle.UnpicklingError"
Guido van Rossum7849da81995-03-09 14:08:35 +0000145
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000146MARK = '('
147STOP = '.'
148POP = '0'
149POP_MARK = '1'
150DUP = '2'
151FLOAT = 'F'
152INT = 'I'
153BININT = 'J'
154BININT1 = 'K'
155LONG = 'L'
156BININT2 = 'M'
157NONE = 'N'
158PERSID = 'P'
159BINPERSID = 'Q'
160REDUCE = 'R'
161STRING = 'S'
162BINSTRING = 'T'
163SHORT_BINSTRING = 'U'
164APPEND = 'a'
165BUILD = 'b'
166GLOBAL = 'c'
167DICT = 'd'
168EMPTY_DICT = '}'
169APPENDS = 'e'
170GET = 'g'
171BINGET = 'h'
172INST = 'i'
173LONG_BINGET = 'j'
174LIST = 'l'
175EMPTY_LIST = ']'
176OBJ = 'o'
177PUT = 'p'
178BINPUT = 'q'
179LONG_BINPUT = 'r'
180SETITEM = 's'
181TUPLE = 't'
182EMPTY_TUPLE = ')'
183SETITEMS = 'u'
Guido van Rossuma48061a1995-01-10 00:31:14 +0000184
185class Pickler:
186
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000187 def __init__(self, file, bin = 0):
188 self.write = file.write
189 self.memo = {}
190 self.bin = bin
Guido van Rossuma48061a1995-01-10 00:31:14 +0000191
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000192 def dump(self, object):
193 self.save(object)
194 self.write(STOP)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000195
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000196 def dump_special(self, callable, args, state = None):
197 if (type(args) is not TupleType):
198 raise PicklingError, "Second argument to dump_special " \
199 "must be a tuple"
Guido van Rossuma48061a1995-01-10 00:31:14 +0000200
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000201 self.save_reduce(callable, args, state)
202 self.write(STOP)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000203
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000204 def put(self, i):
205 if (self.bin):
206 s = mdumps(i)[1:]
207 if (i < 256):
208 return BINPUT + s[0]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000209
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000210 return LONG_BINPUT + s
Guido van Rossuma48061a1995-01-10 00:31:14 +0000211
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000212 return PUT + `i` + '\n'
Guido van Rossuma48061a1995-01-10 00:31:14 +0000213
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000214 def get(self, i):
215 if (self.bin):
216 s = mdumps(i)[1:]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000217
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000218 if (i < 256):
219 return BINGET + s[0]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000220
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000221 return LONG_BINGET + s
Guido van Rossuma48061a1995-01-10 00:31:14 +0000222
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000223 return GET + `i` + '\n'
224
225 def save(self, object, pers_save = 0):
226 memo = self.memo
Guido van Rossuma48061a1995-01-10 00:31:14 +0000227
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000228 if (not pers_save):
229 pid = self.persistent_id(object)
230 if (pid is not None):
231 self.save_pers(pid)
232 return
Guido van Rossuma48061a1995-01-10 00:31:14 +0000233
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000234 d = id(object)
235
236 t = type(object)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000237
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000238 if ((t is TupleType) and (len(object) == 0)):
239 if (self.bin):
240 self.save_empty_tuple(object)
241 else:
242 self.save_tuple(object)
243 return
Guido van Rossuma48061a1995-01-10 00:31:14 +0000244
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000245 if memo.has_key(d):
246 self.write(self.get(memo[d][0]))
247 return
248
249 try:
250 f = self.dispatch[t]
251 except KeyError:
252 pid = self.inst_persistent_id(object)
253 if pid is not None:
254 self.save_pers(pid)
255 return
256
257 try:
258 reduce = dispatch_table[t]
259 except KeyError:
260 try:
261 reduce = object.__reduce__
262 except AttributeError:
263 raise PicklingError, \
264 "can't pickle %s objects" % `t.__name__`
265 else:
266 tup = reduce()
267 else:
268 tup = reduce(object)
269
270 if (type(tup) is not TupleType):
271 raise PicklingError, "Value returned by %s must be a " \
272 "tuple" % reduce
273
274 l = len(tup)
275
276 if ((l != 2) and (l != 3)):
277 raise PicklingError, "tuple returned by %s must contain " \
278 "only two or three elements" % reduce
279
280 callable = tup[0]
281 arg_tup = tup[1]
282
283 if (l > 2):
284 state = tup[2]
285 else:
286 state = None
287
288 if (type(arg_tup) is not TupleType):
289 raise PicklingError, "Second element of tuple returned " \
290 "by %s must be a tuple" % reduce
291
292 self.save_reduce(callable, arg_tup, state)
293 return
294
295 f(self, object)
296
297 def persistent_id(self, object):
298 return None
299
300 def inst_persistent_id(self, object):
301 return None
302
303 def save_pers(self, pid):
304 if (not self.bin):
305 self.write(PERSID + str(pid) + '\n')
306 else:
307 self.save(pid, 1)
308 self.write(BINPERSID)
309
310 def save_reduce(self, callable, arg_tup, state = None):
311 write = self.write
312 save = self.save
313
314 save(callable)
315 save(arg_tup)
316 write(REDUCE)
317
318 if (state is not None):
319 save(state)
320 write(BUILD)
321
322 dispatch = {}
323
324 def save_none(self, object):
325 self.write(NONE)
326 dispatch[NoneType] = save_none
327
328 def save_int(self, object):
329 if (self.bin):
330 i = mdumps(object)[1:]
331 if (i[-2:] == '\000\000'):
332 if (i[-3] == '\000'):
333 self.write(BININT1 + i[:-3])
334 return
335
336 self.write(BININT2 + i[:-2])
337 return
338
339 self.write(BININT + i)
340 else:
341 self.write(INT + `object` + '\n')
342 dispatch[IntType] = save_int
343
344 def save_long(self, object):
345 self.write(LONG + `object` + '\n')
346 dispatch[LongType] = save_long
347
348 def save_float(self, object):
349 self.write(FLOAT + `object` + '\n')
350 dispatch[FloatType] = save_float
351
352 def save_string(self, object):
353 d = id(object)
354 memo = self.memo
355
356 if (self.bin):
357 l = len(object)
358 s = mdumps(l)[1:]
359 if (l < 256):
360 self.write(SHORT_BINSTRING + s[0] + object)
361 else:
362 self.write(BINSTRING + s + object)
363 else:
364 self.write(STRING + `object` + '\n')
365
366 memo_len = len(memo)
367 self.write(self.put(memo_len))
368 memo[d] = (memo_len, object)
369 dispatch[StringType] = save_string
370
371 def save_tuple(self, object):
372
373 write = self.write
374 save = self.save
375 memo = self.memo
376
377 d = id(object)
378
379 write(MARK)
380
381 for element in object:
382 save(element)
383
384 if (len(object) and memo.has_key(d)):
385 if (self.bin):
386 write(POP_MARK + self.get(memo[d][0]))
387 return
388
389 write(POP * (len(object) + 1) + self.get(mem[d][0]))
390 return
391
392 memo_len = len(memo)
393 self.write(TUPLE + self.put(memo_len))
394 memo[d] = (memo_len, object)
395 dispatch[TupleType] = save_tuple
396
397 def save_empty_tuple(self, object):
398 self.write(EMPTY_TUPLE)
399
400 def save_list(self, object):
401 d = id(object)
402
403 write = self.write
404 save = self.save
405 memo = self.memo
406
407 if (self.bin):
408 write(EMPTY_LIST)
409 else:
410 write(MARK + LIST)
411
412 memo_len = len(memo)
413 write(self.put(memo_len))
414 memo[d] = (memo_len, object)
415
416 using_appends = (self.bin and (len(object) > 1))
417
418 if (using_appends):
419 write(MARK)
420
421 for element in object:
422 save(element)
423
424 if (not using_appends):
425 write(APPEND)
426
427 if (using_appends):
428 write(APPENDS)
429 dispatch[ListType] = save_list
430
431 def save_dict(self, object):
432 d = id(object)
433
434 write = self.write
435 save = self.save
436 memo = self.memo
437
438 if (self.bin):
439 write(EMPTY_DICT)
440 else:
441 write(MARK + DICT)
442
443 memo_len = len(memo)
444 self.write(self.put(memo_len))
445 memo[d] = (memo_len, object)
446
447 using_setitems = (self.bin and (len(object) > 1))
448
449 if (using_setitems):
450 write(MARK)
451
452 items = object.items()
453 for key, value in items:
454 save(key)
455 save(value)
456
457 if (not using_setitems):
458 write(SETITEM)
459
460 if (using_setitems):
461 write(SETITEMS)
462
463 dispatch[DictionaryType] = save_dict
464
465 def save_inst(self, object):
466 d = id(object)
467 cls = object.__class__
468
469 memo = self.memo
470 write = self.write
471 save = self.save
472
473 if hasattr(object, '__getinitargs__'):
474 args = object.__getinitargs__()
475 len(args) # XXX Assert it's a sequence
Guido van Rossum5ed5c4c1997-09-03 00:23:54 +0000476 _keep_alive(args, memo)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000477 else:
478 args = ()
479
480 write(MARK)
481
482 if (self.bin):
483 save(cls)
484
485 for arg in args:
486 save(arg)
487
488 memo_len = len(memo)
489 if (self.bin):
490 write(OBJ + self.put(memo_len))
491 else:
492 module = whichmodule(cls, cls.__name__)
493 name = cls.__name__
494 write(INST + module + '\n' + name + '\n' +
495 self.put(memo_len))
496
497 memo[d] = (memo_len, object)
498
499 try:
500 getstate = object.__getstate__
501 except AttributeError:
502 stuff = object.__dict__
503 else:
504 stuff = getstate()
Guido van Rossum5ed5c4c1997-09-03 00:23:54 +0000505 _keep_alive(stuff, memo)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000506 save(stuff)
507 write(BUILD)
508 dispatch[InstanceType] = save_inst
509
510 def save_global(self, object, name = None):
511 write = self.write
512 memo = self.memo
513
514 if (name is None):
515 name = object.__name__
516
517 module = whichmodule(object, name)
518
519 memo_len = len(memo)
520 write(GLOBAL + module + '\n' + name + '\n' +
521 self.put(memo_len))
522 memo[id(object)] = (memo_len, object)
523 dispatch[ClassType] = save_global
524 dispatch[FunctionType] = save_global
525 dispatch[BuiltinFunctionType] = save_global
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000526
Guido van Rossuma48061a1995-01-10 00:31:14 +0000527
Guido van Rossum5ed5c4c1997-09-03 00:23:54 +0000528def _keep_alive(x, memo):
529 """Keeps a reference to the object x in the memo.
530
531 Because we remember objects by their id, we have
532 to assure that possibly temporary objects are kept
533 alive by referencing them.
534 We store a reference at the id of the memo, which should
535 normally not be used unless someone tries to deepcopy
536 the memo itself...
537 """
538 try:
539 memo[id(memo)].append(x)
540 except KeyError:
541 # aha, this is the first one :-)
542 memo[id(memo)]=[x]
543
544
Guido van Rossuma48061a1995-01-10 00:31:14 +0000545classmap = {}
546
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000547def whichmodule(cls, clsname):
548 """Figure out the module in which a class occurs.
Guido van Rossuma48061a1995-01-10 00:31:14 +0000549
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000550 Search sys.modules for the module.
551 Cache in classmap.
552 Return a module name.
553 If the class cannot be found, return __main__.
554 """
555 if classmap.has_key(cls):
556 return classmap[cls]
557 import sys
558
559 for name, module in sys.modules.items():
Guido van Rossum8be9a111997-04-25 19:52:29 +0000560 if name != '__main__' and \
561 hasattr(module, clsname) and \
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000562 getattr(module, clsname) is cls:
563 break
564 else:
565 name = '__main__'
566 classmap[cls] = name
567 return name
Guido van Rossuma48061a1995-01-10 00:31:14 +0000568
569
570class Unpickler:
571
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000572 def __init__(self, file):
573 self.readline = file.readline
574 self.read = file.read
575 self.memo = {}
Guido van Rossuma48061a1995-01-10 00:31:14 +0000576
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000577 def load(self):
578 self.mark = ['spam'] # Any new unique object
579 self.stack = []
580 self.append = self.stack.append
581 read = self.read
582 dispatch = self.dispatch
583 try:
584 while 1:
585 key = read(1)
586 dispatch[key](self)
587 except STOP, value:
588 return value
589
590 def marker(self):
591 stack = self.stack
592 mark = self.mark
593 k = len(stack)-1
594 while stack[k] is not mark: k = k-1
595 return k
596
597 dispatch = {}
598
599 def load_eof(self):
600 raise EOFError
601 dispatch[''] = load_eof
602
603 def load_persid(self):
604 pid = self.readline()[:-1]
605 self.append(self.persistent_load(pid))
606 dispatch[PERSID] = load_persid
607
608 def load_binpersid(self):
609 stack = self.stack
610
611 pid = stack[-1]
612 del stack[-1]
613
614 self.append(self.persistent_load(pid))
615 dispatch[BINPERSID] = load_binpersid
616
617 def load_none(self):
618 self.append(None)
619 dispatch[NONE] = load_none
620
621 def load_int(self):
622 self.append(string.atoi(self.readline()[:-1], 0))
623 dispatch[INT] = load_int
624
625 def load_binint(self):
626 self.append(mloads('i' + self.read(4)))
627 dispatch[BININT] = load_binint
628
629 def load_binint1(self):
630 self.append(mloads('i' + self.read(1) + '\000\000\000'))
631 dispatch[BININT1] = load_binint1
632
633 def load_binint2(self):
634 self.append(mloads('i' + self.read(2) + '\000\000'))
635 dispatch[BININT2] = load_binint2
636
637 def load_long(self):
638 self.append(string.atol(self.readline()[:-1], 0))
639 dispatch[LONG] = load_long
640
641 def load_float(self):
642 self.append(string.atof(self.readline()[:-1]))
643 dispatch[FLOAT] = load_float
644
645 def load_string(self):
646 self.append(eval(self.readline()[:-1],
647 {'__builtins__': {}})) # Let's be careful
648 dispatch[STRING] = load_string
649
650 def load_binstring(self):
651 len = mloads('i' + self.read(4))
652 self.append(self.read(len))
653 dispatch[BINSTRING] = load_binstring
654
655 def load_short_binstring(self):
656 len = mloads('i' + self.read(1) + '\000\000\000')
657 self.append(self.read(len))
658 dispatch[SHORT_BINSTRING] = load_short_binstring
659
660 def load_tuple(self):
661 k = self.marker()
662 self.stack[k:] = [tuple(self.stack[k+1:])]
663 dispatch[TUPLE] = load_tuple
664
665 def load_empty_tuple(self):
666 self.stack.append(())
667 dispatch[EMPTY_TUPLE] = load_empty_tuple
668
669 def load_empty_list(self):
670 self.stack.append([])
671 dispatch[EMPTY_LIST] = load_empty_list
672
673 def load_empty_dictionary(self):
674 self.stack.append({})
675 dispatch[EMPTY_DICT] = load_empty_dictionary
676
677 def load_list(self):
678 k = self.marker()
679 self.stack[k:] = [self.stack[k+1:]]
680 dispatch[LIST] = load_list
681
682 def load_dict(self):
683 k = self.marker()
684 d = {}
685 items = self.stack[k+1:]
686 for i in range(0, len(items), 2):
687 key = items[i]
688 value = items[i+1]
689 d[key] = value
690 self.stack[k:] = [d]
691 dispatch[DICT] = load_dict
692
693 def load_inst(self):
694 k = self.marker()
695 args = tuple(self.stack[k+1:])
696 del self.stack[k:]
697 module = self.readline()[:-1]
698 name = self.readline()[:-1]
699 klass = self.find_class(module, name)
Guido van Rossum8be9a111997-04-25 19:52:29 +0000700## if (type(klass) is not ClassType):
701## raise SystemError, "Imported object %s from module %s is " \
702## "not a class" % (name, module)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000703
704 value = apply(klass, args)
705 self.append(value)
706 dispatch[INST] = load_inst
707
708 def load_obj(self):
709 stack = self.stack
710 k = self.marker()
711 klass = stack[k + 1]
712 del stack[k + 1]
713 args = tuple(stack[k + 1:])
714 del stack[k:]
715 value = apply(klass, args)
716 self.append(value)
717 dispatch[OBJ] = load_obj
718
719 def load_global(self):
720 module = self.readline()[:-1]
721 name = self.readline()[:-1]
722 klass = self.find_class(module, name)
723 self.append(klass)
724 dispatch[GLOBAL] = load_global
725
726 def find_class(self, module, name):
727 env = {}
728
729 try:
730 exec 'from %s import %s' % (module, name) in env
731 except ImportError:
732 raise SystemError, \
733 "Failed to import class %s from module %s" % \
734 (name, module)
735 klass = env[name]
736 return klass
737
738 def load_reduce(self):
739 stack = self.stack
740
741 callable = stack[-2]
742 arg_tup = stack[-1]
743 del stack[-2:]
744
745 if (type(callable) is not ClassType):
746 if (not safe_constructors.has_key(callable)):
Guido van Rossuma48061a1995-01-10 00:31:14 +0000747 try:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000748 safe = callable.__safe_for_unpickling__
749 except AttributeError:
750 safe = None
Guido van Rossuma48061a1995-01-10 00:31:14 +0000751
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000752 if (not safe):
753 raise UnpicklingError, "%s is not safe for " \
754 "unpickling" % callable
Guido van Rossuma48061a1995-01-10 00:31:14 +0000755
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000756 value = apply(callable, arg_tup)
757 self.append(value)
758 dispatch[REDUCE] = load_reduce
Guido van Rossuma48061a1995-01-10 00:31:14 +0000759
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000760 def load_pop(self):
761 del self.stack[-1]
762 dispatch[POP] = load_pop
Guido van Rossum7b5430f1995-03-04 22:25:21 +0000763
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000764 def load_pop_mark(self):
765 k = self.marker()
766 del self.stack[k:]
767 dispatch[POP_MARK] = load_pop_mark
Guido van Rossuma48061a1995-01-10 00:31:14 +0000768
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000769 def load_dup(self):
770 self.append(stack[-1])
771 dispatch[DUP] = load_dup
Guido van Rossuma48061a1995-01-10 00:31:14 +0000772
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000773 def load_get(self):
774 self.append(self.memo[self.readline()[:-1]])
775 dispatch[GET] = load_get
Guido van Rossum78536471996-04-12 13:36:27 +0000776
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000777 def load_binget(self):
778 i = mloads('i' + self.read(1) + '\000\000\000')
779 self.append(self.memo[`i`])
780 dispatch[BINGET] = load_binget
Guido van Rossum78536471996-04-12 13:36:27 +0000781
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000782 def load_long_binget(self):
783 i = mloads('i' + self.read(4))
784 self.append(self.memo[`i`])
785 dispatch[LONG_BINGET] = load_long_binget
Guido van Rossum78536471996-04-12 13:36:27 +0000786
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000787 def load_put(self):
788 self.memo[self.readline()[:-1]] = self.stack[-1]
789 dispatch[PUT] = load_put
Guido van Rossuma48061a1995-01-10 00:31:14 +0000790
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000791 def load_binput(self):
792 i = mloads('i' + self.read(1) + '\000\000\000')
793 self.memo[`i`] = self.stack[-1]
794 dispatch[BINPUT] = load_binput
Guido van Rossuma48061a1995-01-10 00:31:14 +0000795
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000796 def load_long_binput(self):
797 i = mloads('i' + self.read(4))
798 self.memo[`i`] = self.stack[-1]
799 dispatch[LONG_BINPUT] = load_long_binput
Guido van Rossuma48061a1995-01-10 00:31:14 +0000800
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000801 def load_append(self):
802 stack = self.stack
803 value = stack[-1]
804 del stack[-1]
805 list = stack[-1]
806 list.append(value)
807 dispatch[APPEND] = load_append
Guido van Rossuma48061a1995-01-10 00:31:14 +0000808
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000809 def load_appends(self):
810 stack = self.stack
811 mark = self.marker()
812 list = stack[mark - 1]
813 for i in range(mark + 1, len(stack)):
814 list.append(stack[i])
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000815
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000816 del stack[mark:]
817 dispatch[APPENDS] = load_appends
818
819 def load_setitem(self):
820 stack = self.stack
821 value = stack[-1]
822 key = stack[-2]
823 del stack[-2:]
824 dict = stack[-1]
825 dict[key] = value
826 dispatch[SETITEM] = load_setitem
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000827
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000828 def load_setitems(self):
829 stack = self.stack
830 mark = self.marker()
831 dict = stack[mark - 1]
832 for i in range(mark + 1, len(stack), 2):
833 dict[stack[i]] = stack[i + 1]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000834
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000835 del stack[mark:]
836 dispatch[SETITEMS] = load_setitems
Guido van Rossuma48061a1995-01-10 00:31:14 +0000837
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000838 def load_build(self):
839 stack = self.stack
840 value = stack[-1]
841 del stack[-1]
842 inst = stack[-1]
843 try:
844 setstate = inst.__setstate__
845 except AttributeError:
846 for key in value.keys():
847 setattr(inst, key, value[key])
848 else:
849 setstate(value)
850 dispatch[BUILD] = load_build
Guido van Rossuma48061a1995-01-10 00:31:14 +0000851
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000852 def load_mark(self):
853 self.append(self.mark)
854 dispatch[MARK] = load_mark
Guido van Rossuma48061a1995-01-10 00:31:14 +0000855
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000856 def load_stop(self):
857 value = self.stack[-1]
858 del self.stack[-1]
859 raise STOP, value
860 dispatch[STOP] = load_stop
Guido van Rossuma48061a1995-01-10 00:31:14 +0000861
862
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000863# Shorthands
864
Guido van Rossumc7c5e691996-07-22 22:26:07 +0000865from StringIO import StringIO
866
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000867def dump(object, file, bin = 0):
868 Pickler(file, bin).dump(object)
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000869
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000870def dumps(object, bin = 0):
871 file = StringIO()
872 Pickler(file, bin).dump(object)
873 return file.getvalue()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000874
875def load(file):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000876 return Unpickler(file).load()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000877
878def loads(str):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000879 file = StringIO(str)
880 return Unpickler(file).load()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000881
882
883# The rest is used for testing only
884
Guido van Rossuma48061a1995-01-10 00:31:14 +0000885class C:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000886 def __cmp__(self, other):
887 return cmp(self.__dict__, other.__dict__)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000888
889def test():
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000890 fn = 'out'
891 c = C()
892 c.foo = 1
893 c.bar = 2
894 x = [0, 1, 2, 3]
895 y = ('abc', 'abc', c, c)
896 x.append(y)
897 x.append(y)
898 x.append(5)
899 f = open(fn, 'w')
900 F = Pickler(f)
901 F.dump(x)
902 f.close()
903 f = open(fn, 'r')
904 U = Unpickler(f)
905 x2 = U.load()
906 print x
907 print x2
908 print x == x2
909 print map(id, x)
910 print map(id, x2)
911 print F.memo
912 print U.memo
Guido van Rossuma48061a1995-01-10 00:31:14 +0000913
914if __name__ == '__main__':
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000915 test()