blob: ebfde4f1a0c91e4fb2ff4c0b2e9baada8b4021b9 [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""Create portable serialized representations of Python objects.
Guido van Rossuma48061a1995-01-10 00:31:14 +00002
Guido van Rossume467be61997-12-05 19:42:42 +00003See module cPickle for a (much) faster implementation.
4See module copy_reg for a mechanism for registering custom picklers.
Guido van Rossuma48061a1995-01-10 00:31:14 +00005
Guido van Rossume467be61997-12-05 19:42:42 +00006Classes:
Guido van Rossuma48061a1995-01-10 00:31:14 +00007
Guido van Rossume467be61997-12-05 19:42:42 +00008 Pickler
9 Unpickler
Guido van Rossuma48061a1995-01-10 00:31:14 +000010
Guido van Rossume467be61997-12-05 19:42:42 +000011Functions:
Guido van Rossuma48061a1995-01-10 00:31:14 +000012
Guido van Rossume467be61997-12-05 19:42:42 +000013 dump(object, file)
14 dumps(object) -> string
15 load(file) -> object
16 loads(string) -> object
Guido van Rossuma48061a1995-01-10 00:31:14 +000017
Guido van Rossume467be61997-12-05 19:42:42 +000018Misc variables:
Guido van Rossuma48061a1995-01-10 00:31:14 +000019
Fred Drakefe82acc1998-02-13 03:24:48 +000020 __version__
Guido van Rossume467be61997-12-05 19:42:42 +000021 format_version
22 compatible_formats
Guido van Rossuma48061a1995-01-10 00:31:14 +000023
Guido van Rossuma48061a1995-01-10 00:31:14 +000024"""
25
Guido van Rossum743d17e1998-09-15 20:25:57 +000026__version__ = "$Revision$" # Code version
Guido van Rossuma48061a1995-01-10 00:31:14 +000027
28from types import *
Guido van Rossum4fb5b281997-09-12 20:07:24 +000029from copy_reg import dispatch_table, safe_constructors
Guido van Rossumd3703791998-10-22 20:15:36 +000030import string
31import marshal
32import sys
33import struct
Guido van Rossuma48061a1995-01-10 00:31:14 +000034
Guido van Rossumd3703791998-10-22 20:15:36 +000035format_version = "1.3" # File format version we write
36compatible_formats = ["1.0", "1.1", "1.2"] # Old format versions we can read
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000037
38mdumps = marshal.dumps
39mloads = marshal.loads
Guido van Rossum0c891ce1995-03-14 15:09:05 +000040
Guido van Rossum7849da81995-03-09 14:08:35 +000041PicklingError = "pickle.PicklingError"
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000042UnpicklingError = "pickle.UnpicklingError"
Guido van Rossum7849da81995-03-09 14:08:35 +000043
Jeremy Hylton2b9d0291998-05-27 22:38:22 +000044try:
45 from org.python.core import PyStringMap
46except ImportError:
47 PyStringMap = None
48
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000049MARK = '('
50STOP = '.'
51POP = '0'
52POP_MARK = '1'
53DUP = '2'
54FLOAT = 'F'
55INT = 'I'
56BININT = 'J'
57BININT1 = 'K'
58LONG = 'L'
59BININT2 = 'M'
60NONE = 'N'
61PERSID = 'P'
62BINPERSID = 'Q'
63REDUCE = 'R'
64STRING = 'S'
65BINSTRING = 'T'
66SHORT_BINSTRING = 'U'
Guido van Rossumb5f2f1b2000-03-10 23:20:09 +000067UNICODE = 'V'
68BINUNICODE = 'X'
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000069APPEND = 'a'
70BUILD = 'b'
71GLOBAL = 'c'
72DICT = 'd'
73EMPTY_DICT = '}'
74APPENDS = 'e'
75GET = 'g'
76BINGET = 'h'
77INST = 'i'
78LONG_BINGET = 'j'
79LIST = 'l'
80EMPTY_LIST = ']'
81OBJ = 'o'
82PUT = 'p'
83BINPUT = 'q'
84LONG_BINPUT = 'r'
85SETITEM = 's'
86TUPLE = 't'
87EMPTY_TUPLE = ')'
88SETITEMS = 'u'
Guido van Rossumd3703791998-10-22 20:15:36 +000089BINFLOAT = 'G'
Guido van Rossuma48061a1995-01-10 00:31:14 +000090
91class Pickler:
92
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000093 def __init__(self, file, bin = 0):
94 self.write = file.write
95 self.memo = {}
96 self.bin = bin
Guido van Rossuma48061a1995-01-10 00:31:14 +000097
Guido van Rossumb72cf2d1997-04-09 17:32:51 +000098 def dump(self, object):
99 self.save(object)
100 self.write(STOP)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000101
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000102 def put(self, i):
103 if (self.bin):
104 s = mdumps(i)[1:]
105 if (i < 256):
106 return BINPUT + s[0]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000107
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000108 return LONG_BINPUT + s
Guido van Rossuma48061a1995-01-10 00:31:14 +0000109
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000110 return PUT + `i` + '\n'
Guido van Rossuma48061a1995-01-10 00:31:14 +0000111
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000112 def get(self, i):
113 if (self.bin):
114 s = mdumps(i)[1:]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000115
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000116 if (i < 256):
117 return BINGET + s[0]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000118
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000119 return LONG_BINGET + s
Guido van Rossuma48061a1995-01-10 00:31:14 +0000120
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000121 return GET + `i` + '\n'
122
123 def save(self, object, pers_save = 0):
124 memo = self.memo
Guido van Rossuma48061a1995-01-10 00:31:14 +0000125
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000126 if (not pers_save):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000127 pid = self.persistent_id(object)
128 if (pid is not None):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000129 self.save_pers(pid)
130 return
Guido van Rossuma48061a1995-01-10 00:31:14 +0000131
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000132 d = id(object)
133
134 t = type(object)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000135
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000136 if ((t is TupleType) and (len(object) == 0)):
137 if (self.bin):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000138 self.save_empty_tuple(object)
139 else:
140 self.save_tuple(object)
141 return
Guido van Rossuma48061a1995-01-10 00:31:14 +0000142
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000143 if memo.has_key(d):
144 self.write(self.get(memo[d][0]))
145 return
146
147 try:
148 f = self.dispatch[t]
149 except KeyError:
150 pid = self.inst_persistent_id(object)
151 if pid is not None:
152 self.save_pers(pid)
153 return
154
155 try:
156 reduce = dispatch_table[t]
157 except KeyError:
158 try:
159 reduce = object.__reduce__
160 except AttributeError:
161 raise PicklingError, \
Guido van Rossum08a92cb1999-10-10 21:14:25 +0000162 "can't pickle %s object: %s" % (`t.__name__`,
163 `object`)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000164 else:
165 tup = reduce()
166 else:
167 tup = reduce(object)
168
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 if type(tup) is StringType:
170 self.save_global(object, tup)
171 return
Guido van Rossumd1f49841997-12-10 23:40:18 +0000172
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000173 if (type(tup) is not TupleType):
174 raise PicklingError, "Value returned by %s must be a " \
175 "tuple" % reduce
176
177 l = len(tup)
178
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000179 if ((l != 2) and (l != 3)):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000180 raise PicklingError, "tuple returned by %s must contain " \
181 "only two or three elements" % reduce
182
183 callable = tup[0]
184 arg_tup = tup[1]
185
186 if (l > 2):
187 state = tup[2]
188 else:
189 state = None
190
Guido van Rossumd1f49841997-12-10 23:40:18 +0000191 if type(arg_tup) is not TupleType and arg_tup is not None:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000192 raise PicklingError, "Second element of tuple returned " \
193 "by %s must be a tuple" % reduce
194
195 self.save_reduce(callable, arg_tup, state)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000196 memo_len = len(memo)
197 self.write(self.put(memo_len))
198 memo[d] = (memo_len, object)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000199 return
200
201 f(self, object)
202
203 def persistent_id(self, object):
204 return None
205
206 def inst_persistent_id(self, object):
207 return None
208
209 def save_pers(self, pid):
210 if (not self.bin):
211 self.write(PERSID + str(pid) + '\n')
212 else:
213 self.save(pid, 1)
214 self.write(BINPERSID)
215
216 def save_reduce(self, callable, arg_tup, state = None):
217 write = self.write
218 save = self.save
219
220 save(callable)
221 save(arg_tup)
222 write(REDUCE)
223
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000224 if (state is not None):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000225 save(state)
226 write(BUILD)
227
228 dispatch = {}
229
230 def save_none(self, object):
231 self.write(NONE)
232 dispatch[NoneType] = save_none
233
234 def save_int(self, object):
235 if (self.bin):
236 i = mdumps(object)[1:]
237 if (i[-2:] == '\000\000'):
238 if (i[-3] == '\000'):
239 self.write(BININT1 + i[:-3])
240 return
241
242 self.write(BININT2 + i[:-2])
243 return
244
245 self.write(BININT + i)
246 else:
247 self.write(INT + `object` + '\n')
248 dispatch[IntType] = save_int
249
250 def save_long(self, object):
251 self.write(LONG + `object` + '\n')
252 dispatch[LongType] = save_long
253
Guido van Rossumd3703791998-10-22 20:15:36 +0000254 def save_float(self, object, pack=struct.pack):
255 if self.bin:
256 self.write(BINFLOAT + pack('>d', object))
257 else:
258 self.write(FLOAT + `object` + '\n')
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000259 dispatch[FloatType] = save_float
260
261 def save_string(self, object):
262 d = id(object)
263 memo = self.memo
264
265 if (self.bin):
266 l = len(object)
267 s = mdumps(l)[1:]
268 if (l < 256):
269 self.write(SHORT_BINSTRING + s[0] + object)
270 else:
271 self.write(BINSTRING + s + object)
272 else:
273 self.write(STRING + `object` + '\n')
274
275 memo_len = len(memo)
276 self.write(self.put(memo_len))
277 memo[d] = (memo_len, object)
278 dispatch[StringType] = save_string
279
Guido van Rossumb5f2f1b2000-03-10 23:20:09 +0000280 def save_unicode(self, object):
281 d = id(object)
282 memo = self.memo
283
284 if (self.bin):
285 encoding = object.encode('utf-8')
286 l = len(encoding)
287 s = mdumps(l)[1:]
288 self.write(BINUNICODE + s + encoding)
289 else:
290 self.write(UNICODE + object.encode('raw-unicode-escape') + '\n')
291
292 memo_len = len(memo)
293 self.write(self.put(memo_len))
294 memo[d] = (memo_len, object)
295 dispatch[UnicodeType] = save_unicode
296
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000297 def save_tuple(self, object):
298
299 write = self.write
300 save = self.save
301 memo = self.memo
302
303 d = id(object)
304
305 write(MARK)
306
307 for element in object:
308 save(element)
309
310 if (len(object) and memo.has_key(d)):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000311 if (self.bin):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000312 write(POP_MARK + self.get(memo[d][0]))
313 return
314
Guido van Rossum599174f1998-03-31 16:30:28 +0000315 write(POP * (len(object) + 1) + self.get(memo[d][0]))
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000316 return
317
318 memo_len = len(memo)
319 self.write(TUPLE + self.put(memo_len))
320 memo[d] = (memo_len, object)
321 dispatch[TupleType] = save_tuple
322
323 def save_empty_tuple(self, object):
324 self.write(EMPTY_TUPLE)
325
326 def save_list(self, object):
327 d = id(object)
328
329 write = self.write
330 save = self.save
331 memo = self.memo
332
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000333 if (self.bin):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000334 write(EMPTY_LIST)
335 else:
336 write(MARK + LIST)
337
338 memo_len = len(memo)
339 write(self.put(memo_len))
340 memo[d] = (memo_len, object)
341
342 using_appends = (self.bin and (len(object) > 1))
343
344 if (using_appends):
345 write(MARK)
346
347 for element in object:
348 save(element)
349
350 if (not using_appends):
351 write(APPEND)
352
353 if (using_appends):
354 write(APPENDS)
355 dispatch[ListType] = save_list
356
357 def save_dict(self, object):
358 d = id(object)
359
360 write = self.write
361 save = self.save
362 memo = self.memo
363
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000364 if (self.bin):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000365 write(EMPTY_DICT)
366 else:
367 write(MARK + DICT)
368
369 memo_len = len(memo)
370 self.write(self.put(memo_len))
371 memo[d] = (memo_len, object)
372
373 using_setitems = (self.bin and (len(object) > 1))
374
375 if (using_setitems):
376 write(MARK)
377
378 items = object.items()
379 for key, value in items:
380 save(key)
381 save(value)
382
383 if (not using_setitems):
384 write(SETITEM)
385
386 if (using_setitems):
387 write(SETITEMS)
388
389 dispatch[DictionaryType] = save_dict
Jeremy Hylton2b9d0291998-05-27 22:38:22 +0000390 if not PyStringMap is None:
391 dispatch[PyStringMap] = save_dict
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000392
393 def save_inst(self, object):
394 d = id(object)
395 cls = object.__class__
396
397 memo = self.memo
398 write = self.write
399 save = self.save
400
401 if hasattr(object, '__getinitargs__'):
402 args = object.__getinitargs__()
403 len(args) # XXX Assert it's a sequence
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000404 _keep_alive(args, memo)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000405 else:
406 args = ()
407
408 write(MARK)
409
410 if (self.bin):
411 save(cls)
412
413 for arg in args:
414 save(arg)
415
416 memo_len = len(memo)
417 if (self.bin):
418 write(OBJ + self.put(memo_len))
419 else:
Guido van Rossum4fb5b281997-09-12 20:07:24 +0000420 write(INST + cls.__module__ + '\n' + cls.__name__ + '\n' +
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000421 self.put(memo_len))
422
423 memo[d] = (memo_len, object)
424
425 try:
426 getstate = object.__getstate__
427 except AttributeError:
428 stuff = object.__dict__
429 else:
430 stuff = getstate()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000431 _keep_alive(stuff, memo)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000432 save(stuff)
433 write(BUILD)
434 dispatch[InstanceType] = save_inst
435
436 def save_global(self, object, name = None):
437 write = self.write
438 memo = self.memo
439
440 if (name is None):
441 name = object.__name__
442
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000443 try:
444 module = object.__module__
445 except AttributeError:
446 module = whichmodule(object, name)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000447
448 memo_len = len(memo)
449 write(GLOBAL + module + '\n' + name + '\n' +
450 self.put(memo_len))
451 memo[id(object)] = (memo_len, object)
452 dispatch[ClassType] = save_global
453 dispatch[FunctionType] = save_global
454 dispatch[BuiltinFunctionType] = save_global
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000455
Guido van Rossuma48061a1995-01-10 00:31:14 +0000456
Guido van Rossum5ed5c4c1997-09-03 00:23:54 +0000457def _keep_alive(x, memo):
458 """Keeps a reference to the object x in the memo.
459
460 Because we remember objects by their id, we have
461 to assure that possibly temporary objects are kept
462 alive by referencing them.
463 We store a reference at the id of the memo, which should
464 normally not be used unless someone tries to deepcopy
465 the memo itself...
466 """
467 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000468 memo[id(memo)].append(x)
Guido van Rossum5ed5c4c1997-09-03 00:23:54 +0000469 except KeyError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000470 # aha, this is the first one :-)
471 memo[id(memo)]=[x]
Guido van Rossum5ed5c4c1997-09-03 00:23:54 +0000472
473
Guido van Rossuma48061a1995-01-10 00:31:14 +0000474classmap = {}
475
Guido van Rossum4fb5b281997-09-12 20:07:24 +0000476# This is no longer used to find classes, but still for functions
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000477def whichmodule(cls, clsname):
478 """Figure out the module in which a class occurs.
Guido van Rossuma48061a1995-01-10 00:31:14 +0000479
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000480 Search sys.modules for the module.
481 Cache in classmap.
482 Return a module name.
483 If the class cannot be found, return __main__.
484 """
485 if classmap.has_key(cls):
486 return classmap[cls]
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000487
488 for name, module in sys.modules.items():
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000489 if name != '__main__' and \
490 hasattr(module, clsname) and \
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000491 getattr(module, clsname) is cls:
492 break
493 else:
494 name = '__main__'
495 classmap[cls] = name
496 return name
Guido van Rossuma48061a1995-01-10 00:31:14 +0000497
498
499class Unpickler:
500
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000501 def __init__(self, file):
502 self.readline = file.readline
503 self.read = file.read
504 self.memo = {}
Guido van Rossuma48061a1995-01-10 00:31:14 +0000505
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000506 def load(self):
507 self.mark = ['spam'] # Any new unique object
508 self.stack = []
509 self.append = self.stack.append
510 read = self.read
511 dispatch = self.dispatch
512 try:
513 while 1:
514 key = read(1)
515 dispatch[key](self)
516 except STOP, value:
517 return value
518
519 def marker(self):
520 stack = self.stack
521 mark = self.mark
522 k = len(stack)-1
523 while stack[k] is not mark: k = k-1
524 return k
525
526 dispatch = {}
527
528 def load_eof(self):
529 raise EOFError
530 dispatch[''] = load_eof
531
532 def load_persid(self):
533 pid = self.readline()[:-1]
534 self.append(self.persistent_load(pid))
535 dispatch[PERSID] = load_persid
536
537 def load_binpersid(self):
538 stack = self.stack
539
540 pid = stack[-1]
541 del stack[-1]
542
543 self.append(self.persistent_load(pid))
544 dispatch[BINPERSID] = load_binpersid
545
546 def load_none(self):
547 self.append(None)
548 dispatch[NONE] = load_none
549
550 def load_int(self):
Guido van Rossume6805461997-12-10 19:36:41 +0000551 self.append(string.atoi(self.readline()[:-1]))
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000552 dispatch[INT] = load_int
553
554 def load_binint(self):
555 self.append(mloads('i' + self.read(4)))
556 dispatch[BININT] = load_binint
557
558 def load_binint1(self):
559 self.append(mloads('i' + self.read(1) + '\000\000\000'))
560 dispatch[BININT1] = load_binint1
561
562 def load_binint2(self):
563 self.append(mloads('i' + self.read(2) + '\000\000'))
564 dispatch[BININT2] = load_binint2
565
566 def load_long(self):
567 self.append(string.atol(self.readline()[:-1], 0))
568 dispatch[LONG] = load_long
569
570 def load_float(self):
571 self.append(string.atof(self.readline()[:-1]))
572 dispatch[FLOAT] = load_float
573
Guido van Rossumd3703791998-10-22 20:15:36 +0000574 def load_binfloat(self, unpack=struct.unpack):
575 self.append(unpack('>d', self.read(8))[0])
576 dispatch[BINFLOAT] = load_binfloat
577
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000578 def load_string(self):
579 self.append(eval(self.readline()[:-1],
580 {'__builtins__': {}})) # Let's be careful
581 dispatch[STRING] = load_string
582
583 def load_binstring(self):
584 len = mloads('i' + self.read(4))
585 self.append(self.read(len))
586 dispatch[BINSTRING] = load_binstring
587
Guido van Rossumb5f2f1b2000-03-10 23:20:09 +0000588 def load_unicode(self):
589 self.append(unicode(self.readline()[:-1],'raw-unicode-escape'))
590 dispatch[UNICODE] = load_unicode
591
592 def load_binunicode(self):
593 len = mloads('i' + self.read(4))
594 self.append(unicode(self.read(len),'utf-8'))
595 dispatch[BINUNICODE] = load_binunicode
596
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000597 def load_short_binstring(self):
598 len = mloads('i' + self.read(1) + '\000\000\000')
599 self.append(self.read(len))
600 dispatch[SHORT_BINSTRING] = load_short_binstring
601
602 def load_tuple(self):
603 k = self.marker()
604 self.stack[k:] = [tuple(self.stack[k+1:])]
605 dispatch[TUPLE] = load_tuple
606
607 def load_empty_tuple(self):
608 self.stack.append(())
609 dispatch[EMPTY_TUPLE] = load_empty_tuple
610
611 def load_empty_list(self):
612 self.stack.append([])
613 dispatch[EMPTY_LIST] = load_empty_list
614
615 def load_empty_dictionary(self):
616 self.stack.append({})
617 dispatch[EMPTY_DICT] = load_empty_dictionary
618
619 def load_list(self):
620 k = self.marker()
621 self.stack[k:] = [self.stack[k+1:]]
622 dispatch[LIST] = load_list
623
624 def load_dict(self):
625 k = self.marker()
626 d = {}
627 items = self.stack[k+1:]
628 for i in range(0, len(items), 2):
629 key = items[i]
630 value = items[i+1]
631 d[key] = value
632 self.stack[k:] = [d]
633 dispatch[DICT] = load_dict
634
635 def load_inst(self):
636 k = self.marker()
637 args = tuple(self.stack[k+1:])
638 del self.stack[k:]
639 module = self.readline()[:-1]
640 name = self.readline()[:-1]
641 klass = self.find_class(module, name)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000642 instantiated = 0
643 if (not args and type(klass) is ClassType and
644 not hasattr(klass, "__getinitargs__")):
645 try:
646 value = _EmptyClass()
647 value.__class__ = klass
Guido van Rossumb19e2a31998-04-13 18:08:45 +0000648 instantiated = 1
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000649 except RuntimeError:
650 # In restricted execution, assignment to inst.__class__ is
651 # prohibited
652 pass
653 if not instantiated:
Guido van Rossum743d17e1998-09-15 20:25:57 +0000654 try:
655 value = apply(klass, args)
656 except TypeError, err:
657 raise TypeError, "in constructor for %s: %s" % (
658 klass.__name__, str(err)), sys.exc_info()[2]
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000659 self.append(value)
660 dispatch[INST] = load_inst
661
662 def load_obj(self):
663 stack = self.stack
664 k = self.marker()
665 klass = stack[k + 1]
666 del stack[k + 1]
667 args = tuple(stack[k + 1:])
668 del stack[k:]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000669 instantiated = 0
670 if (not args and type(klass) is ClassType and
671 not hasattr(klass, "__getinitargs__")):
672 try:
673 value = _EmptyClass()
674 value.__class__ = klass
675 instantiated = 1
676 except RuntimeError:
677 # In restricted execution, assignment to inst.__class__ is
678 # prohibited
679 pass
680 if not instantiated:
681 value = apply(klass, args)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000682 self.append(value)
683 dispatch[OBJ] = load_obj
684
685 def load_global(self):
686 module = self.readline()[:-1]
687 name = self.readline()[:-1]
688 klass = self.find_class(module, name)
689 self.append(klass)
690 dispatch[GLOBAL] = load_global
691
692 def find_class(self, module, name):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000693 try:
Guido van Rossum397032a1999-03-25 21:58:59 +0000694 __import__(module)
695 mod = sys.modules[module]
696 klass = getattr(mod, name)
697 except (ImportError, KeyError, AttributeError):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000698 raise SystemError, \
699 "Failed to import class %s from module %s" % \
700 (name, module)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000701 return klass
702
703 def load_reduce(self):
704 stack = self.stack
705
706 callable = stack[-2]
707 arg_tup = stack[-1]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000708 del stack[-2:]
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000709
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000710 if type(callable) is not ClassType:
711 if not safe_constructors.has_key(callable):
712 try:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000713 safe = callable.__safe_for_unpickling__
714 except AttributeError:
715 safe = None
Guido van Rossuma48061a1995-01-10 00:31:14 +0000716
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000717 if (not safe):
718 raise UnpicklingError, "%s is not safe for " \
719 "unpickling" % callable
Guido van Rossuma48061a1995-01-10 00:31:14 +0000720
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000721 if arg_tup is None:
722 value = callable.__basicnew__()
723 else:
724 value = apply(callable, arg_tup)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000725 self.append(value)
726 dispatch[REDUCE] = load_reduce
Guido van Rossuma48061a1995-01-10 00:31:14 +0000727
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000728 def load_pop(self):
729 del self.stack[-1]
730 dispatch[POP] = load_pop
Guido van Rossum7b5430f1995-03-04 22:25:21 +0000731
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000732 def load_pop_mark(self):
733 k = self.marker()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000734 del self.stack[k:]
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000735 dispatch[POP_MARK] = load_pop_mark
Guido van Rossuma48061a1995-01-10 00:31:14 +0000736
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000737 def load_dup(self):
Guido van Rossumb1062fc1998-03-31 17:00:46 +0000738 self.append(self.stack[-1])
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000739 dispatch[DUP] = load_dup
Guido van Rossuma48061a1995-01-10 00:31:14 +0000740
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000741 def load_get(self):
742 self.append(self.memo[self.readline()[:-1]])
743 dispatch[GET] = load_get
Guido van Rossum78536471996-04-12 13:36:27 +0000744
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000745 def load_binget(self):
746 i = mloads('i' + self.read(1) + '\000\000\000')
747 self.append(self.memo[`i`])
748 dispatch[BINGET] = load_binget
Guido van Rossum78536471996-04-12 13:36:27 +0000749
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000750 def load_long_binget(self):
751 i = mloads('i' + self.read(4))
752 self.append(self.memo[`i`])
753 dispatch[LONG_BINGET] = load_long_binget
Guido van Rossum78536471996-04-12 13:36:27 +0000754
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000755 def load_put(self):
756 self.memo[self.readline()[:-1]] = self.stack[-1]
757 dispatch[PUT] = load_put
Guido van Rossuma48061a1995-01-10 00:31:14 +0000758
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000759 def load_binput(self):
760 i = mloads('i' + self.read(1) + '\000\000\000')
761 self.memo[`i`] = self.stack[-1]
762 dispatch[BINPUT] = load_binput
Guido van Rossuma48061a1995-01-10 00:31:14 +0000763
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000764 def load_long_binput(self):
765 i = mloads('i' + self.read(4))
766 self.memo[`i`] = self.stack[-1]
767 dispatch[LONG_BINPUT] = load_long_binput
Guido van Rossuma48061a1995-01-10 00:31:14 +0000768
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000769 def load_append(self):
770 stack = self.stack
771 value = stack[-1]
772 del stack[-1]
773 list = stack[-1]
774 list.append(value)
775 dispatch[APPEND] = load_append
Guido van Rossuma48061a1995-01-10 00:31:14 +0000776
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000777 def load_appends(self):
778 stack = self.stack
779 mark = self.marker()
780 list = stack[mark - 1]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000781 for i in range(mark + 1, len(stack)):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000782 list.append(stack[i])
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000783
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000784 del stack[mark:]
785 dispatch[APPENDS] = load_appends
786
787 def load_setitem(self):
788 stack = self.stack
789 value = stack[-1]
790 key = stack[-2]
791 del stack[-2:]
792 dict = stack[-1]
793 dict[key] = value
794 dispatch[SETITEM] = load_setitem
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000795
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000796 def load_setitems(self):
797 stack = self.stack
798 mark = self.marker()
799 dict = stack[mark - 1]
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000800 for i in range(mark + 1, len(stack), 2):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000801 dict[stack[i]] = stack[i + 1]
Guido van Rossuma48061a1995-01-10 00:31:14 +0000802
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000803 del stack[mark:]
804 dispatch[SETITEMS] = load_setitems
Guido van Rossuma48061a1995-01-10 00:31:14 +0000805
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000806 def load_build(self):
807 stack = self.stack
808 value = stack[-1]
809 del stack[-1]
810 inst = stack[-1]
811 try:
812 setstate = inst.__setstate__
813 except AttributeError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000814 try:
815 inst.__dict__.update(value)
816 except RuntimeError:
817 # XXX In restricted execution, the instance's __dict__ is not
818 # accessible. Use the old way of unpickling the instance
819 # variables. This is a semantic different when unpickling in
820 # restricted vs. unrestricted modes.
821 for k, v in value.items():
822 setattr(inst, k, v)
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000823 else:
824 setstate(value)
825 dispatch[BUILD] = load_build
Guido van Rossuma48061a1995-01-10 00:31:14 +0000826
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000827 def load_mark(self):
828 self.append(self.mark)
829 dispatch[MARK] = load_mark
Guido van Rossuma48061a1995-01-10 00:31:14 +0000830
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000831 def load_stop(self):
832 value = self.stack[-1]
833 del self.stack[-1]
834 raise STOP, value
835 dispatch[STOP] = load_stop
Guido van Rossuma48061a1995-01-10 00:31:14 +0000836
Guido van Rossume467be61997-12-05 19:42:42 +0000837# Helper class for load_inst/load_obj
838
839class _EmptyClass:
840 pass
Guido van Rossuma48061a1995-01-10 00:31:14 +0000841
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000842# Shorthands
843
Guido van Rossumc7c5e691996-07-22 22:26:07 +0000844from StringIO import StringIO
845
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000846def dump(object, file, bin = 0):
847 Pickler(file, bin).dump(object)
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000848
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000849def dumps(object, bin = 0):
850 file = StringIO()
851 Pickler(file, bin).dump(object)
852 return file.getvalue()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000853
854def load(file):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000855 return Unpickler(file).load()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000856
857def loads(str):
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000858 file = StringIO(str)
859 return Unpickler(file).load()
Guido van Rossum0c891ce1995-03-14 15:09:05 +0000860
861
862# The rest is used for testing only
863
Guido van Rossuma48061a1995-01-10 00:31:14 +0000864class C:
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000865 def __cmp__(self, other):
866 return cmp(self.__dict__, other.__dict__)
Guido van Rossuma48061a1995-01-10 00:31:14 +0000867
868def test():
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000869 fn = 'out'
870 c = C()
871 c.foo = 1
872 c.bar = 2
873 x = [0, 1, 2, 3]
874 y = ('abc', 'abc', c, c)
875 x.append(y)
876 x.append(y)
877 x.append(5)
878 f = open(fn, 'w')
879 F = Pickler(f)
880 F.dump(x)
881 f.close()
882 f = open(fn, 'r')
883 U = Unpickler(f)
884 x2 = U.load()
885 print x
886 print x2
887 print x == x2
888 print map(id, x)
889 print map(id, x2)
890 print F.memo
891 print U.memo
Guido van Rossuma48061a1995-01-10 00:31:14 +0000892
893if __name__ == '__main__':
Guido van Rossumb72cf2d1997-04-09 17:32:51 +0000894 test()