| 
									
										
										
										
											2000-02-04 15:10:34 +00:00
										 |  |  | """Create portable serialized representations of Python objects.
 | 
					
						
							| 
									
										
										
										
											1997-12-05 19:42:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | See module cPickle for a (much) faster implementation. | 
					
						
							|  |  |  | See module copy_reg for a mechanism for registering custom picklers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Classes: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Pickler | 
					
						
							|  |  |  |     Unpickler | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Functions: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dump(object, file) | 
					
						
							|  |  |  |     dumps(object) -> string | 
					
						
							|  |  |  |     load(file) -> object | 
					
						
							|  |  |  |     loads(string) -> object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Misc variables: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-02-13 03:24:48 +00:00
										 |  |  |     __version__ | 
					
						
							| 
									
										
										
										
											1997-12-05 19:42:42 +00:00
										 |  |  |     format_version | 
					
						
							|  |  |  |     compatible_formats | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-09-15 20:25:57 +00:00
										 |  |  | __version__ = "$Revision$"       # Code version | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | from types import * | 
					
						
							| 
									
										
										
										
											1997-09-12 20:07:24 +00:00
										 |  |  | from copy_reg import dispatch_table, safe_constructors | 
					
						
							| 
									
										
										
										
											1998-10-22 20:15:36 +00:00
										 |  |  | import marshal | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import struct | 
					
						
							| 
									
										
										
										
											2001-02-18 03:10:09 +00:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-07 23:14:30 +00:00
										 |  |  | __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", | 
					
						
							|  |  |  |            "Unpickler", "dump", "dumps", "load", "loads"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-10-22 20:15:36 +00:00
										 |  |  | format_version = "1.3"                     # File format version we write | 
					
						
							|  |  |  | compatible_formats = ["1.0", "1.1", "1.2"] # Old format versions we can read | 
					
						
							| 
									
										
										
										
											1995-03-14 15:09:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | mdumps = marshal.dumps | 
					
						
							|  |  |  | mloads = marshal.loads | 
					
						
							| 
									
										
										
										
											1995-03-09 14:08:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  | class PickleError(Exception): | 
					
						
							| 
									
										
										
										
											2002-05-30 12:12:04 +00:00
										 |  |  |     """A common base class for the other pickling exceptions.""" | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PicklingError(PickleError): | 
					
						
							|  |  |  |     """This exception is raised when an unpicklable object is passed to the
 | 
					
						
							|  |  |  |     dump() method. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class UnpicklingError(PickleError): | 
					
						
							|  |  |  |     """This exception is raised when there is a problem unpickling an object,
 | 
					
						
							|  |  |  |     such as a security violation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Note that other exceptions may also be raised during unpickling, including | 
					
						
							|  |  |  |     (but not necessarily limited to) AttributeError, EOFError, ImportError, | 
					
						
							|  |  |  |     and IndexError. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     pass | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-12-13 18:11:56 +00:00
										 |  |  | class _Stop(Exception): | 
					
						
							|  |  |  |     def __init__(self, value): | 
					
						
							|  |  |  |         self.value = value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-05-27 22:38:22 +00:00
										 |  |  | try: | 
					
						
							|  |  |  |     from org.python.core import PyStringMap | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     PyStringMap = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-09-21 19:22:34 +00:00
										 |  |  | try: | 
					
						
							|  |  |  |     UnicodeType | 
					
						
							|  |  |  | except NameError: | 
					
						
							|  |  |  |     UnicodeType = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | MARK            = '(' | 
					
						
							|  |  |  | STOP            = '.' | 
					
						
							|  |  |  | POP             = '0' | 
					
						
							|  |  |  | POP_MARK        = '1' | 
					
						
							|  |  |  | DUP             = '2' | 
					
						
							|  |  |  | FLOAT           = 'F' | 
					
						
							|  |  |  | INT             = 'I' | 
					
						
							|  |  |  | BININT          = 'J' | 
					
						
							|  |  |  | BININT1         = 'K' | 
					
						
							|  |  |  | LONG            = 'L' | 
					
						
							|  |  |  | BININT2         = 'M' | 
					
						
							|  |  |  | NONE            = 'N' | 
					
						
							|  |  |  | PERSID          = 'P' | 
					
						
							|  |  |  | BINPERSID       = 'Q' | 
					
						
							|  |  |  | REDUCE          = 'R' | 
					
						
							|  |  |  | STRING          = 'S' | 
					
						
							|  |  |  | BINSTRING       = 'T' | 
					
						
							|  |  |  | SHORT_BINSTRING = 'U' | 
					
						
							| 
									
										
										
										
											2000-03-10 23:20:09 +00:00
										 |  |  | UNICODE         = 'V' | 
					
						
							|  |  |  | BINUNICODE      = 'X' | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | APPEND          = 'a' | 
					
						
							|  |  |  | BUILD           = 'b' | 
					
						
							|  |  |  | GLOBAL          = 'c' | 
					
						
							|  |  |  | DICT            = 'd' | 
					
						
							|  |  |  | EMPTY_DICT      = '}' | 
					
						
							|  |  |  | APPENDS         = 'e' | 
					
						
							|  |  |  | GET             = 'g' | 
					
						
							|  |  |  | BINGET          = 'h' | 
					
						
							|  |  |  | INST            = 'i' | 
					
						
							|  |  |  | LONG_BINGET     = 'j' | 
					
						
							|  |  |  | LIST            = 'l' | 
					
						
							|  |  |  | EMPTY_LIST      = ']' | 
					
						
							|  |  |  | OBJ             = 'o' | 
					
						
							|  |  |  | PUT             = 'p' | 
					
						
							|  |  |  | BINPUT          = 'q' | 
					
						
							|  |  |  | LONG_BINPUT     = 'r' | 
					
						
							|  |  |  | SETITEM         = 's' | 
					
						
							|  |  |  | TUPLE           = 't' | 
					
						
							|  |  |  | EMPTY_TUPLE     = ')' | 
					
						
							|  |  |  | SETITEMS        = 'u' | 
					
						
							| 
									
										
										
										
											1998-10-22 20:15:36 +00:00
										 |  |  | BINFLOAT        = 'G' | 
					
						
							| 
									
										
										
										
											2002-04-05 19:30:08 +00:00
										 |  |  | TRUE            = 'I01\n' | 
					
						
							|  |  |  | FALSE           = 'I00\n' | 
					
						
							| 
									
										
										
										
											2002-04-03 22:41:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-18 03:10:09 +00:00
										 |  |  | __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) | 
					
						
							| 
									
										
										
										
											2002-02-11 18:12:06 +00:00
										 |  |  | del x | 
					
						
							| 
									
										
										
										
											2001-02-18 03:10:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-08-14 07:46:28 +00:00
										 |  |  | _quotes = ["'", '"'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | class Pickler: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def __init__(self, file, bin = 0): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |         """This takes a file-like object for writing a pickle data stream.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The optional bin parameter if true, tells the pickler to use the more | 
					
						
							|  |  |  |         efficient binary pickle format, otherwise the ASCII format is used | 
					
						
							|  |  |  |         (this is the default). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The file parameter must have a write() method that accepts a single | 
					
						
							|  |  |  |         string argument.  It can thus be an open file object, a StringIO | 
					
						
							|  |  |  |         object, or any other custom object that meets this interface. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.write = file.write | 
					
						
							|  |  |  |         self.memo = {} | 
					
						
							|  |  |  |         self.bin = bin | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-01 20:33:53 +00:00
										 |  |  |     def clear_memo(self): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |         """Clears the pickler's "memo".
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The memo is the data structure that remembers which objects the | 
					
						
							|  |  |  |         pickler has already seen, so that shared or recursive objects pickled | 
					
						
							|  |  |  |         by reference and not by value.  This method is useful when re-using | 
					
						
							|  |  |  |         picklers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2002-05-01 20:33:53 +00:00
										 |  |  |         self.memo.clear() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def dump(self, object): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |         """Write a pickled representation of object to the open file object.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Either the binary or ASCII format will be used, depending on the | 
					
						
							|  |  |  |         value of the bin flag passed to the constructor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.save(object) | 
					
						
							|  |  |  |         self.write(STOP) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |     def memoize(self, obj): | 
					
						
							|  |  |  |         """Store an object in the memo.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # The memo is a dictionary mapping object ids to 2-tuples | 
					
						
							|  |  |  |         # that contains the memo value and the object being memoized. | 
					
						
							|  |  |  |         # The memo value is written to the pickle and will become | 
					
						
							|  |  |  |         # the key in the Unpickler's memo.  The object is stored in the | 
					
						
							|  |  |  |         # memo so that transient objects are kept alive during pickling. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # The use of the memo length as the memo value is just a convention. | 
					
						
							|  |  |  |         # The only requirement is that the memo values by unique. | 
					
						
							|  |  |  |         d = id(obj) | 
					
						
							|  |  |  |         memo_len = len(self.memo) | 
					
						
							|  |  |  |         self.write(self.put(memo_len)) | 
					
						
							|  |  |  |         self.memo[d] = memo_len, obj | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def put(self, i): | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             s = mdumps(i)[1:] | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if i < 256: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 return BINPUT + s[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return LONG_BINPUT + s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return PUT + `i` + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get(self, i): | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             s = mdumps(i)[1:] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if i < 256: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 return BINGET + s[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return LONG_BINGET + s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return GET + `i` + '\n' | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-13 22:01:27 +00:00
										 |  |  |     def save(self, object): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         memo = self.memo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-13 22:01:27 +00:00
										 |  |  |         pid = self.persistent_id(object) | 
					
						
							|  |  |  |         if pid is not None: | 
					
						
							|  |  |  |             self.save_pers(pid) | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         d = id(object) | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         t = type(object) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if (t is TupleType) and (len(object) == 0): | 
					
						
							|  |  |  |             if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 self.save_empty_tuple(object) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.save_tuple(object) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-01 14:18:47 +00:00
										 |  |  |         if d in memo: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             self.write(self.get(memo[d][0])) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             f = self.dispatch[t] | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							| 
									
										
										
										
											2002-03-26 00:51:56 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 issc = issubclass(t, TypeType) | 
					
						
							|  |  |  |             except TypeError: # t is not a class | 
					
						
							|  |  |  |                 issc = 0 | 
					
						
							|  |  |  |             if issc: | 
					
						
							| 
									
										
										
										
											2001-12-19 16:55:02 +00:00
										 |  |  |                 self.save_global(object) | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 reduce = dispatch_table[t] | 
					
						
							|  |  |  |             except KeyError: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     reduce = object.__reduce__ | 
					
						
							|  |  |  |                 except AttributeError: | 
					
						
							|  |  |  |                     raise PicklingError, \ | 
					
						
							| 
									
										
										
										
											1999-10-10 21:14:25 +00:00
										 |  |  |                         "can't pickle %s object: %s" % (`t.__name__`, | 
					
						
							|  |  |  |                                                          `object`) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     tup = reduce() | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 tup = reduce(object) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             if type(tup) is StringType: | 
					
						
							|  |  |  |                 self.save_global(object, tup) | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											1997-12-10 23:40:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if type(tup) is not TupleType: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 raise PicklingError, "Value returned by %s must be a " \ | 
					
						
							|  |  |  |                                      "tuple" % reduce | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             l = len(tup) | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if (l != 2) and (l != 3): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 raise PicklingError, "tuple returned by %s must contain " \ | 
					
						
							|  |  |  |                                      "only two or three elements" % reduce | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             callable = tup[0] | 
					
						
							|  |  |  |             arg_tup  = tup[1] | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if l > 2: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 state = tup[2] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 state = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-12-10 23:40:18 +00:00
										 |  |  |             if type(arg_tup) is not TupleType and arg_tup is not None: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 raise PicklingError, "Second element of tuple returned " \ | 
					
						
							|  |  |  |                                      "by %s must be a tuple" % reduce | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  |             self.save_reduce(callable, arg_tup, state) | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             memo_len = len(memo) | 
					
						
							|  |  |  |             self.write(self.put(memo_len)) | 
					
						
							|  |  |  |             memo[d] = (memo_len, object) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f(self, object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def persistent_id(self, object): | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_pers(self, pid): | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if not self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             self.write(PERSID + str(pid) + '\n') | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2002-11-13 22:01:27 +00:00
										 |  |  |             self.save(pid) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             self.write(BINPERSID) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |     def save_reduce(self, acallable, arg_tup, state = None): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         write = self.write | 
					
						
							|  |  |  |         save = self.save | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |         if not callable(acallable): | 
					
						
							|  |  |  |             raise PicklingError("__reduce__() must return callable as " | 
					
						
							|  |  |  |                                 "first argument, not %s" % `acallable`) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         save(acallable) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         save(arg_tup) | 
					
						
							|  |  |  |         write(REDUCE) | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if state is not None: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             save(state) | 
					
						
							|  |  |  |             write(BUILD) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dispatch = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_none(self, object): | 
					
						
							|  |  |  |         self.write(NONE) | 
					
						
							|  |  |  |     dispatch[NoneType] = save_none | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-03 22:41:51 +00:00
										 |  |  |     def save_bool(self, object): | 
					
						
							|  |  |  |         if object: | 
					
						
							|  |  |  |             self.write(TRUE) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.write(FALSE) | 
					
						
							|  |  |  |     dispatch[bool] = save_bool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def save_int(self, object): | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											2001-04-10 05:02:52 +00:00
										 |  |  |             # If the int is small enough to fit in a signed 4-byte 2's-comp | 
					
						
							|  |  |  |             # format, we can store it more efficiently than the general | 
					
						
							|  |  |  |             # case. | 
					
						
							|  |  |  |             high_bits = object >> 31  # note that Python shift sign-extends | 
					
						
							|  |  |  |             if  high_bits == 0 or high_bits == -1: | 
					
						
							|  |  |  |                 # All high bits are copies of bit 2**31, so the value | 
					
						
							|  |  |  |                 # fits in a 4-byte signed int. | 
					
						
							|  |  |  |                 i = mdumps(object)[1:] | 
					
						
							|  |  |  |                 assert len(i) == 4 | 
					
						
							|  |  |  |                 if i[-2:] == '\000\000':    # fits in 2-byte unsigned int | 
					
						
							|  |  |  |                     if i[-3] == '\000':     # fits in 1-byte unsigned int | 
					
						
							|  |  |  |                         self.write(BININT1 + i[0]) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.write(BININT2 + i[:2]) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     self.write(BININT + i) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2001-04-10 05:02:52 +00:00
										 |  |  |         # Text pickle, or int too big to fit in signed 4-byte format. | 
					
						
							|  |  |  |         self.write(INT + `object` + '\n') | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[IntType] = save_int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_long(self, object): | 
					
						
							|  |  |  |         self.write(LONG + `object` + '\n') | 
					
						
							|  |  |  |     dispatch[LongType] = save_long | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-10-22 20:15:36 +00:00
										 |  |  |     def save_float(self, object, pack=struct.pack): | 
					
						
							|  |  |  |         if self.bin: | 
					
						
							|  |  |  |             self.write(BINFLOAT + pack('>d', object)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.write(FLOAT + `object` + '\n') | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[FloatType] = save_float | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_string(self, object): | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             l = len(object) | 
					
						
							|  |  |  |             s = mdumps(l)[1:] | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if l < 256: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 self.write(SHORT_BINSTRING + s[0] + object) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.write(BINSTRING + s + object) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.write(STRING + `object` + '\n') | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |         self.memoize(object) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[StringType] = save_string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-10 23:20:09 +00:00
										 |  |  |     def save_unicode(self, object): | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											2000-03-10 23:20:09 +00:00
										 |  |  |             encoding = object.encode('utf-8') | 
					
						
							|  |  |  |             l = len(encoding) | 
					
						
							|  |  |  |             s = mdumps(l)[1:] | 
					
						
							|  |  |  |             self.write(BINUNICODE + s + encoding) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2001-09-21 19:22:34 +00:00
										 |  |  |             object = object.replace("\\", "\\u005c") | 
					
						
							|  |  |  |             object = object.replace("\n", "\\u000a") | 
					
						
							| 
									
										
										
										
											2000-03-10 23:20:09 +00:00
										 |  |  |             self.write(UNICODE + object.encode('raw-unicode-escape') + '\n') | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |         self.memoize(object) | 
					
						
							| 
									
										
										
										
											2000-03-10 23:20:09 +00:00
										 |  |  |     dispatch[UnicodeType] = save_unicode | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-01-22 14:53:29 +00:00
										 |  |  |     if StringType == UnicodeType: | 
					
						
							|  |  |  |         # This is true for Jython | 
					
						
							|  |  |  |         def save_string(self, object): | 
					
						
							|  |  |  |             unicode = object.isunicode() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if self.bin: | 
					
						
							| 
									
										
										
										
											2001-01-22 14:53:29 +00:00
										 |  |  |                 if unicode: | 
					
						
							|  |  |  |                     object = object.encode("utf-8") | 
					
						
							|  |  |  |                 l = len(object) | 
					
						
							|  |  |  |                 s = mdumps(l)[1:] | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |                 if l < 256 and not unicode: | 
					
						
							| 
									
										
										
										
											2001-01-22 14:53:29 +00:00
										 |  |  |                     self.write(SHORT_BINSTRING + s[0] + object) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if unicode: | 
					
						
							|  |  |  |                         self.write(BINUNICODE + s + object) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.write(BINSTRING + s + object) | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2001-02-09 20:06:00 +00:00
										 |  |  |                 if unicode: | 
					
						
							| 
									
										
										
										
											2001-09-21 19:22:34 +00:00
										 |  |  |                     object = object.replace("\\", "\\u005c") | 
					
						
							|  |  |  |                     object = object.replace("\n", "\\u000a") | 
					
						
							| 
									
										
										
										
											2001-01-22 14:53:29 +00:00
										 |  |  |                     object = object.encode('raw-unicode-escape') | 
					
						
							|  |  |  |                     self.write(UNICODE + object + '\n') | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     self.write(STRING + `object` + '\n') | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |             self.memoize(object) | 
					
						
							| 
									
										
										
										
											2001-01-22 14:53:29 +00:00
										 |  |  |         dispatch[StringType] = save_string | 
					
						
							| 
									
										
										
										
											2001-02-09 20:06:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def save_tuple(self, object): | 
					
						
							|  |  |  |         write = self.write | 
					
						
							|  |  |  |         save  = self.save | 
					
						
							|  |  |  |         memo  = self.memo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d = id(object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         write(MARK) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for element in object: | 
					
						
							|  |  |  |             save(element) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-01 14:18:47 +00:00
										 |  |  |         if len(object) and d in memo: | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 write(POP_MARK + self.get(memo[d][0])) | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-31 16:30:28 +00:00
										 |  |  |             write(POP * (len(object) + 1) + self.get(memo[d][0])) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         memo_len = len(memo) | 
					
						
							|  |  |  |         self.write(TUPLE + self.put(memo_len)) | 
					
						
							|  |  |  |         memo[d] = (memo_len, object) | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[TupleType] = save_tuple | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_empty_tuple(self, object): | 
					
						
							|  |  |  |         self.write(EMPTY_TUPLE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_list(self, object): | 
					
						
							|  |  |  |         d = id(object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         write = self.write | 
					
						
							|  |  |  |         save  = self.save | 
					
						
							|  |  |  |         memo  = self.memo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(EMPTY_LIST) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             write(MARK + LIST) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |         self.memoize(object) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         using_appends = (self.bin and (len(object) > 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if using_appends: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(MARK) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for element in object: | 
					
						
							|  |  |  |             save(element) | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if not using_appends: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 write(APPEND) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if using_appends: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(APPENDS) | 
					
						
							|  |  |  |     dispatch[ListType] = save_list | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_dict(self, object): | 
					
						
							|  |  |  |         write = self.write | 
					
						
							|  |  |  |         save  = self.save | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(EMPTY_DICT) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             write(MARK + DICT) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |         self.memoize(object) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         using_setitems = (self.bin and (len(object) > 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if using_setitems: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(MARK) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         items = object.items() | 
					
						
							|  |  |  |         for key, value in items: | 
					
						
							|  |  |  |             save(key) | 
					
						
							|  |  |  |             save(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |             if not using_setitems: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 write(SETITEM) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if using_setitems: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(SETITEMS) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dispatch[DictionaryType] = save_dict | 
					
						
							| 
									
										
										
										
											1998-05-27 22:38:22 +00:00
										 |  |  |     if not PyStringMap is None: | 
					
						
							|  |  |  |         dispatch[PyStringMap] = save_dict | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def save_inst(self, object): | 
					
						
							|  |  |  |         d = id(object) | 
					
						
							|  |  |  |         cls = object.__class__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         memo  = self.memo | 
					
						
							|  |  |  |         write = self.write | 
					
						
							|  |  |  |         save  = self.save | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if hasattr(object, '__getinitargs__'): | 
					
						
							|  |  |  |             args = object.__getinitargs__() | 
					
						
							|  |  |  |             len(args) # XXX Assert it's a sequence | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             _keep_alive(args, memo) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             args = () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         write(MARK) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             save(cls) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for arg in args: | 
					
						
							|  |  |  |             save(arg) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-24 19:29:52 +00:00
										 |  |  |         # This method does not use memoize() so that it can handle | 
					
						
							|  |  |  |         # the special case for non-binary mode. | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         memo_len = len(memo) | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if self.bin: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             write(OBJ + self.put(memo_len)) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											1997-09-12 20:07:24 +00:00
										 |  |  |             write(INST + cls.__module__ + '\n' + cls.__name__ + '\n' + | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                 self.put(memo_len)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         memo[d] = (memo_len, object) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             getstate = object.__getstate__ | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             stuff = object.__dict__ | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             stuff = getstate() | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             _keep_alive(stuff, memo) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         save(stuff) | 
					
						
							|  |  |  |         write(BUILD) | 
					
						
							|  |  |  |     dispatch[InstanceType] = save_inst | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def save_global(self, object, name = None): | 
					
						
							|  |  |  |         write = self.write | 
					
						
							|  |  |  |         memo = self.memo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |         if name is None: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             name = object.__name__ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             module = object.__module__ | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             module = whichmodule(object, name) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-17 18:49:52 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             __import__(module) | 
					
						
							|  |  |  |             mod = sys.modules[module] | 
					
						
							|  |  |  |             klass = getattr(mod, name) | 
					
						
							|  |  |  |         except (ImportError, KeyError, AttributeError): | 
					
						
							|  |  |  |             raise PicklingError( | 
					
						
							|  |  |  |                 "Can't pickle %r: it's not found as %s.%s" % | 
					
						
							|  |  |  |                 (object, module, name)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if klass is not object: | 
					
						
							|  |  |  |                 raise PicklingError( | 
					
						
							|  |  |  |                     "Can't pickle %r: it's not the same object as %s.%s" % | 
					
						
							|  |  |  |                     (object, module, name)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         memo_len = len(memo) | 
					
						
							|  |  |  |         write(GLOBAL + module + '\n' + name + '\n' + | 
					
						
							|  |  |  |             self.put(memo_len)) | 
					
						
							|  |  |  |         memo[id(object)] = (memo_len, object) | 
					
						
							|  |  |  |     dispatch[ClassType] = save_global | 
					
						
							|  |  |  |     dispatch[FunctionType] = save_global | 
					
						
							|  |  |  |     dispatch[BuiltinFunctionType] = save_global | 
					
						
							| 
									
										
										
										
											2001-08-02 04:15:00 +00:00
										 |  |  |     dispatch[TypeType] = save_global | 
					
						
							| 
									
										
										
										
											1995-03-14 15:09:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-09-03 00:23:54 +00:00
										 |  |  | def _keep_alive(x, memo): | 
					
						
							|  |  |  |     """Keeps a reference to the object x in the memo.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Because we remember objects by their id, we have | 
					
						
							|  |  |  |     to assure that possibly temporary objects are kept | 
					
						
							|  |  |  |     alive by referencing them. | 
					
						
							|  |  |  |     We store a reference at the id of the memo, which should | 
					
						
							|  |  |  |     normally not be used unless someone tries to deepcopy | 
					
						
							|  |  |  |     the memo itself... | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         memo[id(memo)].append(x) | 
					
						
							| 
									
										
										
										
											1997-09-03 00:23:54 +00:00
										 |  |  |     except KeyError: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         # aha, this is the first one :-) | 
					
						
							|  |  |  |         memo[id(memo)]=[x] | 
					
						
							| 
									
										
										
										
											1997-09-03 00:23:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  | classmap = {} # called classmap for backwards compatibility | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  | def whichmodule(func, funcname): | 
					
						
							|  |  |  |     """Figure out the module in which a function occurs.
 | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     Search sys.modules for the module. | 
					
						
							|  |  |  |     Cache in classmap. | 
					
						
							|  |  |  |     Return a module name. | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  |     If the function cannot be found, return __main__. | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  |     if func in classmap: | 
					
						
							|  |  |  |         return classmap[func] | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     for name, module in sys.modules.items(): | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  |         if module is None: | 
					
						
							| 
									
										
										
										
											2002-09-19 22:57:26 +00:00
										 |  |  |             continue # skip dummy package entries | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if name != '__main__' and \ | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  |             hasattr(module, funcname) and \ | 
					
						
							|  |  |  |             getattr(module, funcname) is func: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             break | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         name = '__main__' | 
					
						
							| 
									
										
										
										
											2002-09-19 23:00:12 +00:00
										 |  |  |     classmap[func] = name | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     return name | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | class Unpickler: | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def __init__(self, file): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |         """This takes a file-like object for reading a pickle data stream.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This class automatically determines whether the data stream was | 
					
						
							|  |  |  |         written in binary mode or not, so it does not need a flag as in | 
					
						
							|  |  |  |         the Pickler class factory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The file-like object must have two methods, a read() method that | 
					
						
							|  |  |  |         takes an integer argument, and a readline() method that requires no | 
					
						
							|  |  |  |         arguments.  Both methods should return a string.  Thus file-like | 
					
						
							|  |  |  |         object can be a file object opened for reading, a StringIO object, | 
					
						
							|  |  |  |         or any other custom object that meets this interface. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.readline = file.readline | 
					
						
							|  |  |  |         self.read = file.read | 
					
						
							|  |  |  |         self.memo = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load(self): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |         """Read a pickled object representation from the open file object.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Return the reconstituted object hierarchy specified in the file | 
					
						
							|  |  |  |         object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2001-11-09 16:15:04 +00:00
										 |  |  |         self.mark = object() # any new unique object | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.stack = [] | 
					
						
							|  |  |  |         self.append = self.stack.append | 
					
						
							|  |  |  |         read = self.read | 
					
						
							|  |  |  |         dispatch = self.dispatch | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             while 1: | 
					
						
							|  |  |  |                 key = read(1) | 
					
						
							|  |  |  |                 dispatch[key](self) | 
					
						
							| 
									
										
										
										
											2000-12-13 18:11:56 +00:00
										 |  |  |         except _Stop, stopinst: | 
					
						
							|  |  |  |             return stopinst.value | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def marker(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							|  |  |  |         mark = self.mark | 
					
						
							|  |  |  |         k = len(stack)-1 | 
					
						
							|  |  |  |         while stack[k] is not mark: k = k-1 | 
					
						
							|  |  |  |         return k | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dispatch = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_eof(self): | 
					
						
							|  |  |  |         raise EOFError | 
					
						
							|  |  |  |     dispatch[''] = load_eof | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_persid(self): | 
					
						
							|  |  |  |         pid = self.readline()[:-1] | 
					
						
							|  |  |  |         self.append(self.persistent_load(pid)) | 
					
						
							|  |  |  |     dispatch[PERSID] = load_persid | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binpersid(self): | 
					
						
							| 
									
										
										
										
											2002-06-30 03:39:14 +00:00
										 |  |  |         pid = self.stack.pop() | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.append(self.persistent_load(pid)) | 
					
						
							|  |  |  |     dispatch[BINPERSID] = load_binpersid | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_none(self): | 
					
						
							|  |  |  |         self.append(None) | 
					
						
							|  |  |  |     dispatch[NONE] = load_none | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_int(self): | 
					
						
							| 
									
										
										
										
											2001-08-28 22:21:18 +00:00
										 |  |  |         data = self.readline() | 
					
						
							| 
									
										
										
										
											2002-04-05 19:30:08 +00:00
										 |  |  |         if data == FALSE[1:]: | 
					
						
							|  |  |  |             val = False | 
					
						
							|  |  |  |         elif data == TRUE[1:]: | 
					
						
							|  |  |  |             val = True | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 val = int(data) | 
					
						
							|  |  |  |             except ValueError: | 
					
						
							|  |  |  |                 val = long(data) | 
					
						
							|  |  |  |         self.append(val) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[INT] = load_int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binint(self): | 
					
						
							|  |  |  |         self.append(mloads('i' + self.read(4))) | 
					
						
							|  |  |  |     dispatch[BININT] = load_binint | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binint1(self): | 
					
						
							|  |  |  |         self.append(mloads('i' + self.read(1) + '\000\000\000')) | 
					
						
							|  |  |  |     dispatch[BININT1] = load_binint1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binint2(self): | 
					
						
							|  |  |  |         self.append(mloads('i' + self.read(2) + '\000\000')) | 
					
						
							|  |  |  |     dispatch[BININT2] = load_binint2 | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def load_long(self): | 
					
						
							| 
									
										
										
										
											2000-12-13 18:11:56 +00:00
										 |  |  |         self.append(long(self.readline()[:-1], 0)) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[LONG] = load_long | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_float(self): | 
					
						
							| 
									
										
										
										
											2000-12-13 18:11:56 +00:00
										 |  |  |         self.append(float(self.readline()[:-1])) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[FLOAT] = load_float | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-10-22 20:15:36 +00:00
										 |  |  |     def load_binfloat(self, unpack=struct.unpack): | 
					
						
							|  |  |  |         self.append(unpack('>d', self.read(8))[0]) | 
					
						
							|  |  |  |     dispatch[BINFLOAT] = load_binfloat | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def load_string(self): | 
					
						
							| 
									
										
										
										
											2000-09-15 15:14:51 +00:00
										 |  |  |         rep = self.readline()[:-1] | 
					
						
							| 
									
										
										
										
											2002-08-14 07:46:28 +00:00
										 |  |  |         for q in _quotes: | 
					
						
							|  |  |  |             if rep.startswith(q): | 
					
						
							|  |  |  |                 if not rep.endswith(q): | 
					
						
							|  |  |  |                     raise ValueError, "insecure string pickle" | 
					
						
							|  |  |  |                 rep = rep[len(q):-len(q)] | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2000-09-15 15:14:51 +00:00
										 |  |  |             raise ValueError, "insecure string pickle" | 
					
						
							| 
									
										
										
										
											2002-08-14 07:46:28 +00:00
										 |  |  |         self.append(rep.decode("string-escape")) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[STRING] = load_string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-15 15:14:51 +00:00
										 |  |  |     def _is_string_secure(self, s): | 
					
						
							|  |  |  |         """Return true if s contains a string that is safe to eval
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The definition of secure string is based on the implementation | 
					
						
							|  |  |  |         in cPickle.  s is secure as long as it only contains a quoted | 
					
						
							|  |  |  |         string and optional trailing whitespace. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         q = s[0] | 
					
						
							|  |  |  |         if q not in ("'", '"'): | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |         # find the closing quote | 
					
						
							|  |  |  |         offset = 1 | 
					
						
							|  |  |  |         i = None | 
					
						
							|  |  |  |         while 1: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 i = s.index(q, offset) | 
					
						
							|  |  |  |             except ValueError: | 
					
						
							|  |  |  |                 # if there is an error the first time, there is no | 
					
						
							|  |  |  |                 # close quote | 
					
						
							|  |  |  |                 if offset == 1: | 
					
						
							|  |  |  |                     return 0 | 
					
						
							|  |  |  |             if s[i-1] != '\\': | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             # check to see if this one is escaped | 
					
						
							|  |  |  |             nslash = 0 | 
					
						
							|  |  |  |             j = i - 1 | 
					
						
							|  |  |  |             while j >= offset and s[j] == '\\': | 
					
						
							|  |  |  |                 j = j - 1 | 
					
						
							|  |  |  |                 nslash = nslash + 1 | 
					
						
							|  |  |  |             if nslash % 2 == 0: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             offset = i + 1 | 
					
						
							|  |  |  |         for c in s[i+1:]: | 
					
						
							|  |  |  |             if ord(c) > 32: | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def load_binstring(self): | 
					
						
							|  |  |  |         len = mloads('i' + self.read(4)) | 
					
						
							|  |  |  |         self.append(self.read(len)) | 
					
						
							|  |  |  |     dispatch[BINSTRING] = load_binstring | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-10 23:20:09 +00:00
										 |  |  |     def load_unicode(self): | 
					
						
							|  |  |  |         self.append(unicode(self.readline()[:-1],'raw-unicode-escape')) | 
					
						
							|  |  |  |     dispatch[UNICODE] = load_unicode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binunicode(self): | 
					
						
							|  |  |  |         len = mloads('i' + self.read(4)) | 
					
						
							|  |  |  |         self.append(unicode(self.read(len),'utf-8')) | 
					
						
							|  |  |  |     dispatch[BINUNICODE] = load_binunicode | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def load_short_binstring(self): | 
					
						
							|  |  |  |         len = mloads('i' + self.read(1) + '\000\000\000') | 
					
						
							|  |  |  |         self.append(self.read(len)) | 
					
						
							|  |  |  |     dispatch[SHORT_BINSTRING] = load_short_binstring | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_tuple(self): | 
					
						
							|  |  |  |         k = self.marker() | 
					
						
							|  |  |  |         self.stack[k:] = [tuple(self.stack[k+1:])] | 
					
						
							|  |  |  |     dispatch[TUPLE] = load_tuple | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_empty_tuple(self): | 
					
						
							|  |  |  |         self.stack.append(()) | 
					
						
							|  |  |  |     dispatch[EMPTY_TUPLE] = load_empty_tuple | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_empty_list(self): | 
					
						
							|  |  |  |         self.stack.append([]) | 
					
						
							|  |  |  |     dispatch[EMPTY_LIST] = load_empty_list | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_empty_dictionary(self): | 
					
						
							|  |  |  |         self.stack.append({}) | 
					
						
							|  |  |  |     dispatch[EMPTY_DICT] = load_empty_dictionary | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_list(self): | 
					
						
							|  |  |  |         k = self.marker() | 
					
						
							|  |  |  |         self.stack[k:] = [self.stack[k+1:]] | 
					
						
							|  |  |  |     dispatch[LIST] = load_list | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_dict(self): | 
					
						
							|  |  |  |         k = self.marker() | 
					
						
							|  |  |  |         d = {} | 
					
						
							|  |  |  |         items = self.stack[k+1:] | 
					
						
							|  |  |  |         for i in range(0, len(items), 2): | 
					
						
							|  |  |  |             key = items[i] | 
					
						
							|  |  |  |             value = items[i+1] | 
					
						
							|  |  |  |             d[key] = value | 
					
						
							|  |  |  |         self.stack[k:] = [d] | 
					
						
							|  |  |  |     dispatch[DICT] = load_dict | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_inst(self): | 
					
						
							|  |  |  |         k = self.marker() | 
					
						
							|  |  |  |         args = tuple(self.stack[k+1:]) | 
					
						
							|  |  |  |         del self.stack[k:] | 
					
						
							|  |  |  |         module = self.readline()[:-1] | 
					
						
							|  |  |  |         name = self.readline()[:-1] | 
					
						
							|  |  |  |         klass = self.find_class(module, name) | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         instantiated = 0 | 
					
						
							|  |  |  |         if (not args and type(klass) is ClassType and | 
					
						
							|  |  |  |             not hasattr(klass, "__getinitargs__")): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 value = _EmptyClass() | 
					
						
							|  |  |  |                 value.__class__ = klass | 
					
						
							| 
									
										
										
										
											1998-04-13 18:08:45 +00:00
										 |  |  |                 instantiated = 1 | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             except RuntimeError: | 
					
						
							|  |  |  |                 # In restricted execution, assignment to inst.__class__ is | 
					
						
							|  |  |  |                 # prohibited | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         if not instantiated: | 
					
						
							| 
									
										
										
										
											1998-09-15 20:25:57 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2001-11-15 23:42:58 +00:00
										 |  |  |                 if not hasattr(klass, '__safe_for_unpickling__'): | 
					
						
							|  |  |  |                     raise UnpicklingError('%s is not safe for unpickling' % | 
					
						
							|  |  |  |                                           klass) | 
					
						
							| 
									
										
										
										
											1998-09-15 20:25:57 +00:00
										 |  |  |                 value = apply(klass, args) | 
					
						
							|  |  |  |             except TypeError, err: | 
					
						
							|  |  |  |                 raise TypeError, "in constructor for %s: %s" % ( | 
					
						
							|  |  |  |                     klass.__name__, str(err)), sys.exc_info()[2] | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.append(value) | 
					
						
							|  |  |  |     dispatch[INST] = load_inst | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_obj(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							|  |  |  |         k = self.marker() | 
					
						
							|  |  |  |         klass = stack[k + 1] | 
					
						
							|  |  |  |         del stack[k + 1] | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  |         args = tuple(stack[k + 1:]) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         del stack[k:] | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         instantiated = 0 | 
					
						
							|  |  |  |         if (not args and type(klass) is ClassType and | 
					
						
							|  |  |  |             not hasattr(klass, "__getinitargs__")): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 value = _EmptyClass() | 
					
						
							|  |  |  |                 value.__class__ = klass | 
					
						
							|  |  |  |                 instantiated = 1 | 
					
						
							|  |  |  |             except RuntimeError: | 
					
						
							|  |  |  |                 # In restricted execution, assignment to inst.__class__ is | 
					
						
							|  |  |  |                 # prohibited | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         if not instantiated: | 
					
						
							|  |  |  |             value = apply(klass, args) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.append(value) | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  |     dispatch[OBJ] = load_obj | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def load_global(self): | 
					
						
							|  |  |  |         module = self.readline()[:-1] | 
					
						
							|  |  |  |         name = self.readline()[:-1] | 
					
						
							|  |  |  |         klass = self.find_class(module, name) | 
					
						
							|  |  |  |         self.append(klass) | 
					
						
							|  |  |  |     dispatch[GLOBAL] = load_global | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def find_class(self, module, name): | 
					
						
							| 
									
										
										
										
											2001-11-15 23:42:58 +00:00
										 |  |  |         __import__(module) | 
					
						
							|  |  |  |         mod = sys.modules[module] | 
					
						
							|  |  |  |         klass = getattr(mod, name) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         return klass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_reduce(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         callable = stack[-2] | 
					
						
							|  |  |  |         arg_tup  = stack[-1] | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         del stack[-2:] | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if type(callable) is not ClassType: | 
					
						
							| 
									
										
										
										
											2002-06-01 14:18:47 +00:00
										 |  |  |             if not callable in safe_constructors: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |                     safe = callable.__safe_for_unpickling__ | 
					
						
							|  |  |  |                 except AttributeError: | 
					
						
							|  |  |  |                     safe = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-10 02:48:53 +00:00
										 |  |  |                 if not safe: | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  |                     raise UnpicklingError, "%s is not safe for " \ | 
					
						
							|  |  |  |                                            "unpickling" % callable | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if arg_tup is None: | 
					
						
							| 
									
										
										
										
											2002-05-21 17:22:02 +00:00
										 |  |  |             import warnings | 
					
						
							|  |  |  |             warnings.warn("The None return argument form of __reduce__  is " | 
					
						
							|  |  |  |                           "deprecated. Return a tuple of arguments instead.", | 
					
						
							| 
									
										
										
										
											2002-05-23 15:15:30 +00:00
										 |  |  |                           DeprecationWarning) | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             value = callable.__basicnew__() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             value = apply(callable, arg_tup) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         self.append(value) | 
					
						
							|  |  |  |     dispatch[REDUCE] = load_reduce | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_pop(self): | 
					
						
							|  |  |  |         del self.stack[-1] | 
					
						
							|  |  |  |     dispatch[POP] = load_pop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_pop_mark(self): | 
					
						
							|  |  |  |         k = self.marker() | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         del self.stack[k:] | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[POP_MARK] = load_pop_mark | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_dup(self): | 
					
						
							| 
									
										
										
										
											1998-03-31 17:00:46 +00:00
										 |  |  |         self.append(self.stack[-1]) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[DUP] = load_dup | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_get(self): | 
					
						
							|  |  |  |         self.append(self.memo[self.readline()[:-1]]) | 
					
						
							|  |  |  |     dispatch[GET] = load_get | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binget(self): | 
					
						
							|  |  |  |         i = mloads('i' + self.read(1) + '\000\000\000') | 
					
						
							|  |  |  |         self.append(self.memo[`i`]) | 
					
						
							|  |  |  |     dispatch[BINGET] = load_binget | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_long_binget(self): | 
					
						
							|  |  |  |         i = mloads('i' + self.read(4)) | 
					
						
							|  |  |  |         self.append(self.memo[`i`]) | 
					
						
							|  |  |  |     dispatch[LONG_BINGET] = load_long_binget | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_put(self): | 
					
						
							|  |  |  |         self.memo[self.readline()[:-1]] = self.stack[-1] | 
					
						
							|  |  |  |     dispatch[PUT] = load_put | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_binput(self): | 
					
						
							|  |  |  |         i = mloads('i' + self.read(1) + '\000\000\000') | 
					
						
							|  |  |  |         self.memo[`i`] = self.stack[-1] | 
					
						
							|  |  |  |     dispatch[BINPUT] = load_binput | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_long_binput(self): | 
					
						
							|  |  |  |         i = mloads('i' + self.read(4)) | 
					
						
							|  |  |  |         self.memo[`i`] = self.stack[-1] | 
					
						
							|  |  |  |     dispatch[LONG_BINPUT] = load_long_binput | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_append(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							| 
									
										
										
										
											2002-06-30 03:39:14 +00:00
										 |  |  |         value = stack.pop() | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         list = stack[-1] | 
					
						
							|  |  |  |         list.append(value) | 
					
						
							|  |  |  |     dispatch[APPEND] = load_append | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_appends(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							|  |  |  |         mark = self.marker() | 
					
						
							|  |  |  |         list = stack[mark - 1] | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         for i in range(mark + 1, len(stack)): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             list.append(stack[i]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         del stack[mark:] | 
					
						
							|  |  |  |     dispatch[APPENDS] = load_appends | 
					
						
							| 
									
										
										
										
											2001-01-15 00:50:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     def load_setitem(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							| 
									
										
										
										
											2002-06-30 03:39:14 +00:00
										 |  |  |         value = stack.pop() | 
					
						
							|  |  |  |         key = stack.pop() | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         dict = stack[-1] | 
					
						
							|  |  |  |         dict[key] = value | 
					
						
							|  |  |  |     dispatch[SETITEM] = load_setitem | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_setitems(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							|  |  |  |         mark = self.marker() | 
					
						
							|  |  |  |         dict = stack[mark - 1] | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         for i in range(mark + 1, len(stack), 2): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |             dict[stack[i]] = stack[i + 1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         del stack[mark:] | 
					
						
							|  |  |  |     dispatch[SETITEMS] = load_setitems | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_build(self): | 
					
						
							|  |  |  |         stack = self.stack | 
					
						
							| 
									
										
										
										
											2002-06-30 03:39:14 +00:00
										 |  |  |         value = stack.pop() | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         inst = stack[-1] | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             setstate = inst.__setstate__ | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 inst.__dict__.update(value) | 
					
						
							|  |  |  |             except RuntimeError: | 
					
						
							|  |  |  |                 # XXX In restricted execution, the instance's __dict__ is not | 
					
						
							|  |  |  |                 # accessible.  Use the old way of unpickling the instance | 
					
						
							|  |  |  |                 # variables.  This is a semantic different when unpickling in | 
					
						
							|  |  |  |                 # restricted vs. unrestricted modes. | 
					
						
							|  |  |  |                 for k, v in value.items(): | 
					
						
							|  |  |  |                     setattr(inst, k, v) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             setstate(value) | 
					
						
							|  |  |  |     dispatch[BUILD] = load_build | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_mark(self): | 
					
						
							|  |  |  |         self.append(self.mark) | 
					
						
							|  |  |  |     dispatch[MARK] = load_mark | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_stop(self): | 
					
						
							| 
									
										
										
										
											2002-06-30 03:39:14 +00:00
										 |  |  |         value = self.stack.pop() | 
					
						
							| 
									
										
										
										
											2000-12-13 18:11:56 +00:00
										 |  |  |         raise _Stop(value) | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     dispatch[STOP] = load_stop | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-12-05 19:42:42 +00:00
										 |  |  | # Helper class for load_inst/load_obj | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _EmptyClass: | 
					
						
							|  |  |  |     pass | 
					
						
							| 
									
										
										
										
											1995-01-10 00:31:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-14 15:09:05 +00:00
										 |  |  | # Shorthands | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-10-15 21:29:28 +00:00
										 |  |  | try: | 
					
						
							|  |  |  |     from cStringIO import StringIO | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     from StringIO import StringIO | 
					
						
							| 
									
										
										
										
											1996-07-22 22:26:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | def dump(object, file, bin = 0): | 
					
						
							|  |  |  |     Pickler(file, bin).dump(object) | 
					
						
							| 
									
										
										
										
											1995-03-14 15:09:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  | def dumps(object, bin = 0): | 
					
						
							|  |  |  |     file = StringIO() | 
					
						
							|  |  |  |     Pickler(file, bin).dump(object) | 
					
						
							|  |  |  |     return file.getvalue() | 
					
						
							| 
									
										
										
										
											1995-03-14 15:09:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def load(file): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     return Unpickler(file).load() | 
					
						
							| 
									
										
										
										
											1995-03-14 15:09:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def loads(str): | 
					
						
							| 
									
										
										
										
											1997-04-09 17:32:51 +00:00
										 |  |  |     file = StringIO(str) | 
					
						
							|  |  |  |     return Unpickler(file).load() |