1 """Create portable serialized representations of Python objects.
3 See module cPickle for a (much) faster implementation.
4 See module copy_reg for a mechanism for registering custom picklers.
14 dumps(object) -> string
16 loads(string) -> object
26 __version__
= "$Revision$" # Code version
29 from copy_reg
import dispatch_table
, safe_constructors
35 __all__
= ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
36 "Unpickler", "dump", "dumps", "load", "loads"]
38 format_version
= "1.3" # File format version we write
39 compatible_formats
= ["1.0", "1.1", "1.2"] # Old format versions we can read
41 mdumps
= marshal
.dumps
42 mloads
= marshal
.loads
44 class PickleError(Exception): pass
45 class PicklingError(PickleError
): pass
46 class UnpicklingError(PickleError
): pass
48 class _Stop(Exception):
49 def __init__(self
, value
):
53 from org
.python
.core
import PyStringMap
99 __all__
.extend([x
for x
in dir() if re
.match("[A-Z][A-Z0-9_]+$",x
)])
103 def __init__(self
, file, bin
= 0):
104 self
.write
= file.write
108 def dump(self
, object):
118 return LONG_BINPUT
+ s
120 return PUT
+ `i`
+ '\n'
129 return LONG_BINGET
+ s
131 return GET
+ `i`
+ '\n'
133 def save(self
, object, pers_save
= 0):
137 pid
= self
.persistent_id(object)
146 if (t
is TupleType
) and (len(object) == 0):
148 self
.save_empty_tuple(object)
150 self
.save_tuple(object)
154 self
.write(self
.get(memo
[d
][0]))
160 pid
= self
.inst_persistent_id(object)
166 reduce = dispatch_table
[t
]
169 reduce = object.__reduce
__
170 except AttributeError:
171 raise PicklingError
, \
172 "can't pickle %s object: %s" % (`t
.__name
__`
,
179 if type(tup
) is StringType
:
180 self
.save_global(object, tup
)
183 if type(tup
) is not TupleType
:
184 raise PicklingError
, "Value returned by %s must be a " \
189 if (l
!= 2) and (l
!= 3):
190 raise PicklingError
, "tuple returned by %s must contain " \
191 "only two or three elements" % reduce
201 if type(arg_tup
) is not TupleType
and arg_tup
is not None:
202 raise PicklingError
, "Second element of tuple returned " \
203 "by %s must be a tuple" % reduce
205 self
.save_reduce(callable, arg_tup
, state
)
207 self
.write(self
.put(memo_len
))
208 memo
[d
] = (memo_len
, object)
213 def persistent_id(self
, object):
216 def inst_persistent_id(self
, object):
219 def save_pers(self
, pid
):
221 self
.write(PERSID
+ str(pid
) + '\n')
224 self
.write(BINPERSID
)
226 def save_reduce(self
, callable, arg_tup
, state
= None):
234 if state
is not None:
240 def save_none(self
, object):
242 dispatch
[NoneType
] = save_none
244 def save_int(self
, object):
246 # If the int is small enough to fit in a signed 4-byte 2's-comp
247 # format, we can store it more efficiently than the general
249 high_bits
= object >> 31 # note that Python shift sign-extends
250 if high_bits
== 0 or high_bits
== -1:
251 # All high bits are copies of bit 2**31, so the value
252 # fits in a 4-byte signed int.
253 i
= mdumps(object)[1:]
255 if i
[-2:] == '\000\000': # fits in 2-byte unsigned int
256 if i
[-3] == '\000': # fits in 1-byte unsigned int
257 self
.write(BININT1
+ i
[0])
259 self
.write(BININT2
+ i
[:2])
261 self
.write(BININT
+ i
)
263 # Text pickle, or int too big to fit in signed 4-byte format.
264 self
.write(INT
+ `
object`
+ '\n')
265 dispatch
[IntType
] = save_int
267 def save_long(self
, object):
268 self
.write(LONG
+ `
object`
+ '\n')
269 dispatch
[LongType
] = save_long
271 def save_float(self
, object, pack
=struct
.pack
):
273 self
.write(BINFLOAT
+ pack('>d', object))
275 self
.write(FLOAT
+ `
object`
+ '\n')
276 dispatch
[FloatType
] = save_float
278 def save_string(self
, object):
286 self
.write(SHORT_BINSTRING
+ s
[0] + object)
288 self
.write(BINSTRING
+ s
+ object)
290 self
.write(STRING
+ `
object`
+ '\n')
293 self
.write(self
.put(memo_len
))
294 memo
[d
] = (memo_len
, object)
295 dispatch
[StringType
] = save_string
297 def save_unicode(self
, object):
302 encoding
= object.encode('utf-8')
305 self
.write(BINUNICODE
+ s
+ encoding
)
307 object = object.replace(u
"\\", u
"\\u005c")
308 object = object.replace(u
"\n", u
"\\u000a")
309 self
.write(UNICODE
+ object.encode('raw-unicode-escape') + '\n')
312 self
.write(self
.put(memo_len
))
313 memo
[d
] = (memo_len
, object)
314 dispatch
[UnicodeType
] = save_unicode
316 if StringType
== UnicodeType
:
317 # This is true for Jython
318 def save_string(self
, object):
321 unicode = object.isunicode()
325 object = object.encode("utf-8")
328 if l
< 256 and not unicode:
329 self
.write(SHORT_BINSTRING
+ s
[0] + object)
332 self
.write(BINUNICODE
+ s
+ object)
334 self
.write(BINSTRING
+ s
+ object)
337 object = object.replace(u
"\\", u
"\\u005c")
338 object = object.replace(u
"\n", u
"\\u000a")
339 object = object.encode('raw-unicode-escape')
340 self
.write(UNICODE
+ object + '\n')
342 self
.write(STRING
+ `
object`
+ '\n')
345 self
.write(self
.put(memo_len
))
346 memo
[d
] = (memo_len
, object)
347 dispatch
[StringType
] = save_string
349 def save_tuple(self
, object):
359 for element
in object:
362 if len(object) and memo
.has_key(d
):
364 write(POP_MARK
+ self
.get(memo
[d
][0]))
367 write(POP
* (len(object) + 1) + self
.get(memo
[d
][0]))
371 self
.write(TUPLE
+ self
.put(memo_len
))
372 memo
[d
] = (memo_len
, object)
373 dispatch
[TupleType
] = save_tuple
375 def save_empty_tuple(self
, object):
376 self
.write(EMPTY_TUPLE
)
378 def save_list(self
, object):
391 write(self
.put(memo_len
))
392 memo
[d
] = (memo_len
, object)
394 using_appends
= (self
.bin
and (len(object) > 1))
399 for element
in object:
402 if not using_appends
:
407 dispatch
[ListType
] = save_list
409 def save_dict(self
, object):
422 self
.write(self
.put(memo_len
))
423 memo
[d
] = (memo_len
, object)
425 using_setitems
= (self
.bin
and (len(object) > 1))
430 items
= object.items()
431 for key
, value
in items
:
435 if not using_setitems
:
441 dispatch
[DictionaryType
] = save_dict
442 if not PyStringMap
is None:
443 dispatch
[PyStringMap
] = save_dict
445 def save_inst(self
, object):
447 cls
= object.__class
__
453 if hasattr(object, '__getinitargs__'):
454 args
= object.__getinitargs
__()
455 len(args
) # XXX Assert it's a sequence
456 _keep_alive(args
, memo
)
470 write(OBJ
+ self
.put(memo_len
))
472 write(INST
+ cls
.__module
__ + '\n' + cls
.__name
__ + '\n' +
475 memo
[d
] = (memo_len
, object)
478 getstate
= object.__getstate
__
479 except AttributeError:
480 stuff
= object.__dict
__
483 _keep_alive(stuff
, memo
)
486 dispatch
[InstanceType
] = save_inst
488 def save_global(self
, object, name
= None):
493 name
= object.__name
__
496 module
= object.__module
__
497 except AttributeError:
498 module
= whichmodule(object, name
)
501 write(GLOBAL
+ module
+ '\n' + name
+ '\n' +
503 memo
[id(object)] = (memo_len
, object)
504 dispatch
[ClassType
] = save_global
505 dispatch
[FunctionType
] = save_global
506 dispatch
[BuiltinFunctionType
] = save_global
509 def _keep_alive(x
, memo
):
510 """Keeps a reference to the object x in the memo.
512 Because we remember objects by their id, we have
513 to assure that possibly temporary objects are kept
514 alive by referencing them.
515 We store a reference at the id of the memo, which should
516 normally not be used unless someone tries to deepcopy
520 memo
[id(memo
)].append(x
)
522 # aha, this is the first one :-)
528 # This is no longer used to find classes, but still for functions
529 def whichmodule(cls
, clsname
):
530 """Figure out the module in which a class occurs.
532 Search sys.modules for the module.
534 Return a module name.
535 If the class cannot be found, return __main__.
537 if classmap
.has_key(cls
):
540 for name
, module
in sys
.modules
.items():
541 if name
!= '__main__' and \
542 hasattr(module
, clsname
) and \
543 getattr(module
, clsname
) is cls
:
553 def __init__(self
, file):
554 self
.readline
= file.readline
555 self
.read
= file.read
559 self
.mark
= ['spam'] # Any new unique object
561 self
.append
= self
.stack
.append
563 dispatch
= self
.dispatch
568 except _Stop
, stopinst
:
569 return stopinst
.value
575 while stack
[k
] is not mark
: k
= k
-1
582 dispatch
[''] = load_eof
584 def load_persid(self
):
585 pid
= self
.readline()[:-1]
586 self
.append(self
.persistent_load(pid
))
587 dispatch
[PERSID
] = load_persid
589 def load_binpersid(self
):
595 self
.append(self
.persistent_load(pid
))
596 dispatch
[BINPERSID
] = load_binpersid
600 dispatch
[NONE
] = load_none
603 self
.append(int(self
.readline()[:-1]))
604 dispatch
[INT
] = load_int
606 def load_binint(self
):
607 self
.append(mloads('i' + self
.read(4)))
608 dispatch
[BININT
] = load_binint
610 def load_binint1(self
):
611 self
.append(mloads('i' + self
.read(1) + '\000\000\000'))
612 dispatch
[BININT1
] = load_binint1
614 def load_binint2(self
):
615 self
.append(mloads('i' + self
.read(2) + '\000\000'))
616 dispatch
[BININT2
] = load_binint2
619 self
.append(long(self
.readline()[:-1], 0))
620 dispatch
[LONG
] = load_long
622 def load_float(self
):
623 self
.append(float(self
.readline()[:-1]))
624 dispatch
[FLOAT
] = load_float
626 def load_binfloat(self
, unpack
=struct
.unpack
):
627 self
.append(unpack('>d', self
.read(8))[0])
628 dispatch
[BINFLOAT
] = load_binfloat
630 def load_string(self
):
631 rep
= self
.readline()[:-1]
632 if not self
._is
_string
_secure
(rep
):
633 raise ValueError, "insecure string pickle"
634 self
.append(eval(rep
,
635 {'__builtins__': {}})) # Let's be careful
636 dispatch
[STRING
] = load_string
638 def _is_string_secure(self
, s
):
639 """Return true if s contains a string that is safe to eval
641 The definition of secure string is based on the implementation
642 in cPickle. s is secure as long as it only contains a quoted
643 string and optional trailing whitespace.
646 if q
not in ("'", '"'):
648 # find the closing quote
653 i
= s
.index(q
, offset
)
655 # if there is an error the first time, there is no
661 # check to see if this one is escaped
664 while j
>= offset
and s
[j
] == '\\':
675 def load_binstring(self
):
676 len = mloads('i' + self
.read(4))
677 self
.append(self
.read(len))
678 dispatch
[BINSTRING
] = load_binstring
680 def load_unicode(self
):
681 self
.append(unicode(self
.readline()[:-1],'raw-unicode-escape'))
682 dispatch
[UNICODE
] = load_unicode
684 def load_binunicode(self
):
685 len = mloads('i' + self
.read(4))
686 self
.append(unicode(self
.read(len),'utf-8'))
687 dispatch
[BINUNICODE
] = load_binunicode
689 def load_short_binstring(self
):
690 len = mloads('i' + self
.read(1) + '\000\000\000')
691 self
.append(self
.read(len))
692 dispatch
[SHORT_BINSTRING
] = load_short_binstring
694 def load_tuple(self
):
696 self
.stack
[k
:] = [tuple(self
.stack
[k
+1:])]
697 dispatch
[TUPLE
] = load_tuple
699 def load_empty_tuple(self
):
700 self
.stack
.append(())
701 dispatch
[EMPTY_TUPLE
] = load_empty_tuple
703 def load_empty_list(self
):
704 self
.stack
.append([])
705 dispatch
[EMPTY_LIST
] = load_empty_list
707 def load_empty_dictionary(self
):
708 self
.stack
.append({})
709 dispatch
[EMPTY_DICT
] = load_empty_dictionary
713 self
.stack
[k
:] = [self
.stack
[k
+1:]]
714 dispatch
[LIST
] = load_list
719 items
= self
.stack
[k
+1:]
720 for i
in range(0, len(items
), 2):
725 dispatch
[DICT
] = load_dict
729 args
= tuple(self
.stack
[k
+1:])
731 module
= self
.readline()[:-1]
732 name
= self
.readline()[:-1]
733 klass
= self
.find_class(module
, name
)
735 if (not args
and type(klass
) is ClassType
and
736 not hasattr(klass
, "__getinitargs__")):
738 value
= _EmptyClass()
739 value
.__class
__ = klass
742 # In restricted execution, assignment to inst.__class__ is
747 value
= apply(klass
, args
)
748 except TypeError, err
:
749 raise TypeError, "in constructor for %s: %s" % (
750 klass
.__name
__, str(err
)), sys
.exc_info()[2]
752 dispatch
[INST
] = load_inst
759 args
= tuple(stack
[k
+ 1:])
762 if (not args
and type(klass
) is ClassType
and
763 not hasattr(klass
, "__getinitargs__")):
765 value
= _EmptyClass()
766 value
.__class
__ = klass
769 # In restricted execution, assignment to inst.__class__ is
773 value
= apply(klass
, args
)
775 dispatch
[OBJ
] = load_obj
777 def load_global(self
):
778 module
= self
.readline()[:-1]
779 name
= self
.readline()[:-1]
780 klass
= self
.find_class(module
, name
)
782 dispatch
[GLOBAL
] = load_global
784 def find_class(self
, module
, name
):
787 mod
= sys
.modules
[module
]
788 klass
= getattr(mod
, name
)
789 except (ImportError, KeyError, AttributeError):
791 "Failed to import class %s from module %s" % \
795 def load_reduce(self
):
802 if type(callable) is not ClassType
:
803 if not safe_constructors
.has_key(callable):
805 safe
= callable.__safe
_for
_unpickling
__
806 except AttributeError:
810 raise UnpicklingError
, "%s is not safe for " \
811 "unpickling" % callable
814 value
= callable.__basicnew
__()
816 value
= apply(callable, arg_tup
)
818 dispatch
[REDUCE
] = load_reduce
822 dispatch
[POP
] = load_pop
824 def load_pop_mark(self
):
827 dispatch
[POP_MARK
] = load_pop_mark
830 self
.append(self
.stack
[-1])
831 dispatch
[DUP
] = load_dup
834 self
.append(self
.memo
[self
.readline()[:-1]])
835 dispatch
[GET
] = load_get
837 def load_binget(self
):
838 i
= mloads('i' + self
.read(1) + '\000\000\000')
839 self
.append(self
.memo
[`i`
])
840 dispatch
[BINGET
] = load_binget
842 def load_long_binget(self
):
843 i
= mloads('i' + self
.read(4))
844 self
.append(self
.memo
[`i`
])
845 dispatch
[LONG_BINGET
] = load_long_binget
848 self
.memo
[self
.readline()[:-1]] = self
.stack
[-1]
849 dispatch
[PUT
] = load_put
851 def load_binput(self
):
852 i
= mloads('i' + self
.read(1) + '\000\000\000')
853 self
.memo
[`i`
] = self
.stack
[-1]
854 dispatch
[BINPUT
] = load_binput
856 def load_long_binput(self
):
857 i
= mloads('i' + self
.read(4))
858 self
.memo
[`i`
] = self
.stack
[-1]
859 dispatch
[LONG_BINPUT
] = load_long_binput
861 def load_append(self
):
867 dispatch
[APPEND
] = load_append
869 def load_appends(self
):
872 list = stack
[mark
- 1]
873 for i
in range(mark
+ 1, len(stack
)):
874 list.append(stack
[i
])
877 dispatch
[APPENDS
] = load_appends
879 def load_setitem(self
):
886 dispatch
[SETITEM
] = load_setitem
888 def load_setitems(self
):
891 dict = stack
[mark
- 1]
892 for i
in range(mark
+ 1, len(stack
), 2):
893 dict[stack
[i
]] = stack
[i
+ 1]
896 dispatch
[SETITEMS
] = load_setitems
898 def load_build(self
):
904 setstate
= inst
.__setstate
__
905 except AttributeError:
907 inst
.__dict
__.update(value
)
909 # XXX In restricted execution, the instance's __dict__ is not
910 # accessible. Use the old way of unpickling the instance
911 # variables. This is a semantic different when unpickling in
912 # restricted vs. unrestricted modes.
913 for k
, v
in value
.items():
917 dispatch
[BUILD
] = load_build
920 self
.append(self
.mark
)
921 dispatch
[MARK
] = load_mark
924 value
= self
.stack
[-1]
927 dispatch
[STOP
] = load_stop
929 # Helper class for load_inst/load_obj
936 from StringIO
import StringIO
938 def dump(object, file, bin
= 0):
939 Pickler(file, bin
).dump(object)
941 def dumps(object, bin
= 0):
943 Pickler(file, bin
).dump(object)
944 return file.getvalue()
947 return Unpickler(file).load()
951 return Unpickler(file).load()
954 # The rest is used for testing only
957 def __cmp__(self
, other
):
958 return cmp(self
.__dict
__, other
.__dict
__)
966 y
= ('abc', 'abc', c
, c
)
985 if __name__
== '__main__':