14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Create portable serialized representations of Python objects. 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSee module cPickle for a (much) faster implementation. 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSee module copy_reg for a mechanism for registering custom picklers. 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSee module pickletools source for extensive comments. 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmClasses: 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Pickler 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Unpickler 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmFunctions: 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dump(object, file) 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dumps(object) -> string 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm load(file) -> object 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm loads(string) -> object 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmMisc variables: 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __version__ 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format_version 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm compatible_formats 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__version__ = "$Revision$" # Code version 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom types import * 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom copy_reg import dispatch_table 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom copy_reg import _extension_registry, _inverted_registry, _extension_cache 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport marshal 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport struct 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport re 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Unpickler", "dump", "dumps", "load", "loads"] 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# These are purely informational; no code uses these. 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmformat_version = "2.0" # File format version we write 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcompatible_formats = ["1.0", # Original protocol 0 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "1.1", # Protocol 0 with INST added 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "1.2", # Original protocol 1 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "1.3", # Protocol 1 with BINFLOAT added 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "2.0", # Protocol 2 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ] # Old format versions we can read 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Keep in synch with cPickle. This is the highest protocol number we 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# know how to read. 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmHIGHEST_PROTOCOL = 2 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Why use struct.pack() for pickling but marshal.loads() for 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# unpickling? struct.pack() is 40% faster than marshal.dumps(), but 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# marshal.loads() is twice as fast as struct.unpack()! 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmloads = marshal.loads 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass PickleError(Exception): 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A common base class for the other pickling exceptions.""" 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass PicklingError(PickleError): 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """This exception is raised when an unpicklable object is passed to the 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dump() method. 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass UnpicklingError(PickleError): 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """This exception is raised when there is a problem unpickling an object, 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm such as a security violation. 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Note that other exceptions may also be raised during unpickling, including 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (but not necessarily limited to) AttributeError, EOFError, ImportError, 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm and IndexError. 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# An instance of _Stop is raised by Unpickler.load_stop() in response to 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# the STOP opcode, passing the object that is the result of unpickling. 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass _Stop(Exception): 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, value): 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.value = value 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Jython has PyStringMap; it's a dict subclass with string keys 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from org.python.core import PyStringMap 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept ImportError: 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyStringMap = None 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# UnicodeType may or may not be exported (normally imported from types) 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm UnicodeType 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept NameError: 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm UnicodeType = None 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Pickle opcodes. See pickletools.py for extensive docs. The listing 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# here is in kind-of alphabetical order of 1-character pickle code. 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# pickletools groups them by purpose. 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmMARK = '(' # push special markobject on stack 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSTOP = '.' # every pickle ends with STOP 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPOP = '0' # discard topmost stack item 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPOP_MARK = '1' # discard stack top through topmost markobject 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDUP = '2' # duplicate top stack item 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmFLOAT = 'F' # push float object; decimal string argument 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmINT = 'I' # push integer or bool; decimal string argument 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBININT = 'J' # push four-byte signed int 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBININT1 = 'K' # push 1-byte unsigned int 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLONG = 'L' # push long; decimal string argument 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBININT2 = 'M' # push 2-byte unsigned int 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNONE = 'N' # push None 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPERSID = 'P' # push persistent object; id is taken from string arg 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBINPERSID = 'Q' # " " " ; " " " " stack 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmREDUCE = 'R' # apply callable to argtuple, both on stack 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSTRING = 'S' # push string; NL-terminated string argument 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBINSTRING = 'T' # push string; counted binary string argument 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSHORT_BINSTRING = 'U' # " " ; " " " " < 256 bytes 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmUNICODE = 'V' # push Unicode string; raw-unicode-escaped'd argument 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBINUNICODE = 'X' # " " " ; counted UTF-8 string argument 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmAPPEND = 'a' # append stack top to list below it 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBUILD = 'b' # call __setstate__ or __dict__.update() 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmGLOBAL = 'c' # push self.find_class(modname, name); 2 string args 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDICT = 'd' # build a dict from stack items 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEMPTY_DICT = '}' # push empty dict 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmAPPENDS = 'e' # extend list on stack by topmost stack slice 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmGET = 'g' # push item from memo on stack; index is string arg 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBINGET = 'h' # " " " " " " ; " " 1-byte arg 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmINST = 'i' # build & push class instance 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLONG_BINGET = 'j' # push item from memo on stack; index is 4-byte arg 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLIST = 'l' # build list from topmost stack items 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEMPTY_LIST = ']' # push empty list 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmOBJ = 'o' # build & push class instance 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPUT = 'p' # store stack top in memo; index is string arg 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBINPUT = 'q' # " " " " " ; " " 1-byte arg 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLONG_BINPUT = 'r' # " " " " " ; " " 4-byte arg 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSETITEM = 's' # add key+value pair to dict 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTUPLE = 't' # build tuple from topmost stack items 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEMPTY_TUPLE = ')' # push empty tuple 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSETITEMS = 'u' # modify dict by adding topmost key+value pairs 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBINFLOAT = 'G' # push float; arg is 8-byte float encoding 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTRUE = 'I01\n' # not an opcode; see INT docs in pickletools.py 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmFALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Protocol 2 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPROTO = '\x80' # identify pickle protocol 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNEWOBJ = '\x81' # build object by applying cls.__new__ to argtuple 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEXT1 = '\x82' # push object from extension registry; 1-byte index 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEXT2 = '\x83' # ditto, but 2-byte index 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEXT4 = '\x84' # ditto, but 4-byte index 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTUPLE1 = '\x85' # build 1-tuple from stack top 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTUPLE2 = '\x86' # build 2-tuple from two topmost stack items 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTUPLE3 = '\x87' # build 3-tuple from three topmost stack items 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNEWTRUE = '\x88' # push True 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNEWFALSE = '\x89' # push False 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLONG1 = '\x8a' # push long from < 256 bytes 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLONG4 = '\x8b' # push really big long 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3] 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdel x 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Pickling machinery 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Pickler: 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, file, protocol=None): 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """This takes a file-like object for writing a pickle data stream. 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional protocol argument tells the pickler to use the 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm given protocol; supported protocols are 0, 1, 2. The default 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm protocol is 0, to be backwards compatible. (Protocol 0 is the 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm only protocol that can be written to a file opened in text 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mode and read back successfully. When using a protocol higher 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm than 0, make sure the file is opened in binary mode, both when 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pickling and unpickling.) 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Protocol 1 is more efficient than protocol 0; protocol 2 is 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more efficient than protocol 1. 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Specifying a negative protocol version selects the highest 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm protocol version supported. The higher the protocol used, the 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more recent the version of Python needed to read the pickle 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm produced. 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The file parameter must have a write() method that accepts a single 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string argument. It can thus be an open file object, a StringIO 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object, or any other custom object that meets this interface. 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if protocol is None: 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm protocol = 0 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if protocol < 0: 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm protocol = HIGHEST_PROTOCOL 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif not 0 <= protocol <= HIGHEST_PROTOCOL: 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL) 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write = file.write 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo = {} 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.proto = int(protocol) 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.bin = protocol >= 1 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fast = 0 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def clear_memo(self): 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Clears the pickler's "memo". 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The memo is the data structure that remembers which objects the 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pickler has already seen, so that shared or recursive objects are 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pickled by reference and not by value. This method is useful when 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm re-using picklers. 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo.clear() 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def dump(self, obj): 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Write a pickled representation of obj to the open file.""" 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.proto >= 2: 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(PROTO + chr(self.proto)) 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save(obj) 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(STOP) 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def memoize(self, obj): 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Store an object in the memo.""" 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The Pickler memo is a dictionary mapping object ids to 2-tuples 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # that contain the Unpickler memo key and the object being memoized. 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The memo key is written to the pickle and will become 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the key in the Unpickler's memo. The object is stored in the 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Pickler memo so that transient objects are kept alive during 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # pickling. 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The use of the Unpickler memo length as the memo key is just a 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # convention. The only requirement is that the memo values be unique. 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # But there appears no advantage to any other scheme, and this 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # scheme allows the Unpickler memo to be implemented as a plain (but 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # growable) array, indexed by memo key. 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.fast: 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert id(obj) not in self.memo 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo_len = len(self.memo) 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(self.put(memo_len)) 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo[id(obj)] = memo_len, obj 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i. 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def put(self, i, pack=struct.pack): 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if i < 256: 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return BINPUT + chr(i) 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return LONG_BINPUT + pack("<i", i) 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PUT + repr(i) + '\n' 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i. 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def get(self, i, pack=struct.pack): 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if i < 256: 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return BINGET + chr(i) 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return LONG_BINGET + pack("<i", i) 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return GET + repr(i) + '\n' 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save(self, obj): 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check for persistent id (defined by a subclass) 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pid = self.persistent_id(obj) 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if pid: 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save_pers(pid) 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check the memo 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = self.memo.get(id(obj)) 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if x: 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(self.get(x[0])) 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check the type dispatch table 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t = type(obj) 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = self.dispatch.get(t) 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if f: 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f(self, obj) # Call unbound method with explicit self 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check for a class with a custom metaclass; treat as regular class 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm issc = issubclass(t, TypeType) 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError: # t is not a class (old Boost; see SF #502085) 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm issc = 0 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if issc: 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save_global(obj) 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check copy_reg.dispatch_table 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reduce = dispatch_table.get(t) 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reduce: 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reduce(obj) 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check for a __reduce_ex__ method, fall back to __reduce__ 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reduce = getattr(obj, "__reduce_ex__", None) 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reduce: 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reduce(self.proto) 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reduce = getattr(obj, "__reduce__", None) 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reduce: 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reduce() 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError("Can't pickle %r object: %r" % 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (t.__name__, obj)) 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Check for string returned by reduce(), meaning "save as global" 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if type(rv) is StringType: 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save_global(obj, rv) 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Assert that reduce() returned a tuple 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if type(rv) is not TupleType: 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError("%s must return string or tuple" % reduce) 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Assert that it returned an appropriately sized tuple 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l = len(rv) 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not (2 <= l <= 5): 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError("Tuple returned by %s must have " 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "two to five elements" % reduce) 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Save the reduce() output and finally memoize the object 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save_reduce(obj=obj, *rv) 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def persistent_id(self, obj): 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This exists so a subclass can override it 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_pers(self, pid): 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Save a persistent id reference 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.save(pid) 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BINPERSID) 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(PERSID + str(pid) + '\n') 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_reduce(self, func, args, state=None, 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm listitems=None, dictitems=None, obj=None): 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This API is called by some subclasses 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Assert that args is a tuple or None 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not isinstance(args, TupleType): 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError("args from reduce() should be a tuple") 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Assert that func is callable 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not hasattr(func, '__call__'): 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError("func from reduce should be callable") 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save = self.save 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Protocol 2 special case: if func's name is __newobj__, use NEWOBJ 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.proto >= 2 and getattr(func, "__name__", "") == "__newobj__": 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A __reduce__ implementation can direct protocol 2 to 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # use the more efficient NEWOBJ opcode, while still 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # allowing protocol 0 and 1 to work normally. For this to 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # work, the function returned by __reduce__ should be 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # called __newobj__, and its first argument should be a 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # new-style class. The implementation for __newobj__ 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # should be as follows, although pickle has no way to 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # verify this: 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # def __newobj__(cls, *args): 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # return cls.__new__(cls, *args) 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Protocols 0 and 1 will pickle a reference to __newobj__, 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # while protocol 2 (and above) will pickle a reference to 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # cls, the remaining args tuple, and the NEWOBJ code, 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # which calls cls.__new__(cls, *args) at unpickling time 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # (see load_newobj below). If __reduce__ returns a 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # three-tuple, the state from the third tuple item will be 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # pickled regardless of the protocol, calling __setstate__ 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # at unpickling time (see load_build below). 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note that no standard __newobj__ implementation exists; 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # you have to provide your own. This is to enforce 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # compatibility with Python 2.2 (pickles written using 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # protocol 0 or 1 in Python 2.3 should be unpicklable by 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Python 2.2). 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cls = args[0] 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not hasattr(cls, "__new__"): 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError( 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "args[0] from __newobj__ args has no __new__") 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj is not None and cls is not obj.__class__: 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError( 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "args[0] from __newobj__ args has the wrong class") 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = args[1:] 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(cls) 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(args) 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(NEWOBJ) 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(func) 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(args) 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(REDUCE) 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj is not None: 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # More new special cases (that work with older protocols as 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # well): when __reduce__ returns a tuple with 4 or 5 items, 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the 4th and 5th item should be iterators that provide list 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # items and dict items (as (key, value) tuples), or None. 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if listitems is not None: 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._batch_appends(listitems) 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if dictitems is not None: 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._batch_setitems(dictitems) 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if state is not None: 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(state) 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(BUILD) 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Methods below this point are dispatched through the dispatch table 4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch = {} 4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_none(self, obj): 4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(NONE) 4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[NoneType] = save_none 4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_bool(self, obj): 4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.proto >= 2: 4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(obj and NEWTRUE or NEWFALSE) 4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(obj and TRUE or FALSE) 4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[bool] = save_bool 4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_int(self, obj, pack=struct.pack): 4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If the int is small enough to fit in a signed 4-byte 2's-comp 4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # format, we can store it more efficiently than the general 4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # case. 4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # First one- and two-byte unsigned ints: 4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj >= 0: 4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj <= 0xff: 4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BININT1 + chr(obj)) 4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj <= 0xffff: 4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8)) 4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Next check for 4-byte signed ints: 4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm high_bits = obj >> 31 # note that Python shift sign-extends 4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if high_bits == 0 or high_bits == -1: 4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # All high bits are copies of bit 2**31, so the value 4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # fits in a 4-byte signed int. 4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BININT + pack("<i", obj)) 4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Text pickle, or int too big to fit in signed 4-byte format. 4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(INT + repr(obj) + '\n') 4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[IntType] = save_int 4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_long(self, obj, pack=struct.pack): 4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.proto >= 2: 4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bytes = encode_long(obj) 4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(bytes) 4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n < 256: 4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(LONG1 + chr(n) + bytes) 4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(LONG4 + pack("<i", n) + bytes) 4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(LONG + repr(obj) + '\n') 4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LongType] = save_long 4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_float(self, obj, pack=struct.pack): 4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BINFLOAT + pack('>d', obj)) 4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(FLOAT + repr(obj) + '\n') 4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[FloatType] = save_float 4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_string(self, obj, pack=struct.pack): 4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(obj) 4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n < 256: 4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(SHORT_BINSTRING + chr(n) + obj) 4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BINSTRING + pack("<i", n) + obj) 4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(STRING + repr(obj) + '\n') 4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[StringType] = save_string 4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_unicode(self, obj, pack=struct.pack): 4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding = obj.encode('utf-8') 4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(encoding) 4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BINUNICODE + pack("<i", n) + encoding) 4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = obj.replace("\\", "\\u005c") 4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = obj.replace("\n", "\\u000a") 5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(UNICODE + obj.encode('raw-unicode-escape') + '\n') 5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[UnicodeType] = save_unicode 5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if StringType is UnicodeType: 5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This is true for Jython 5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_string(self, obj, pack=struct.pack): 5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unicode = obj.isunicode() 5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if unicode: 5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = obj.encode("utf-8") 5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l = len(obj) 5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if l < 256 and not unicode: 5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(SHORT_BINSTRING + chr(l) + obj) 5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = pack("<i", l) 5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if unicode: 5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BINUNICODE + s + obj) 5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(BINSTRING + s + obj) 5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if unicode: 5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = obj.replace("\\", "\\u005c") 5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = obj.replace("\n", "\\u000a") 5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = obj.encode('raw-unicode-escape') 5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(UNICODE + obj + '\n') 5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(STRING + repr(obj) + '\n') 5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[StringType] = save_string 5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_tuple(self, obj): 5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm proto = self.proto 5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(obj) 5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n == 0: 5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if proto: 5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(EMPTY_TUPLE) 5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK + TUPLE) 5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save = self.save 5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo = self.memo 5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n <= 3 and proto >= 2: 5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for element in obj: 5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(element) 5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Subtle. Same as in the big comment below. 5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if id(obj) in memo: 5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm get = self.get(memo[id(obj)][0]) 5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(POP * n + get) 5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(_tuplesize2code[n]) 5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # proto 0 or proto 1 and tuple isn't empty, or proto > 1 and tuple 5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # has more than 3 elements. 5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK) 5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for element in obj: 5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(element) 5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if id(obj) in memo: 5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Subtle. d was not in memo when we entered save_tuple(), so 5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the process of saving the tuple's elements must have saved 5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the tuple itself: the tuple is recursive. The proper action 5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # now is to throw away everything we put on the stack, and 5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # simply GET the tuple (it's already constructed). This check 5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # could have been done in the "for element" loop instead, but 5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # recursive tuples are a rare thing. 5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm get = self.get(memo[id(obj)][0]) 5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if proto: 5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(POP_MARK + get) 5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: # proto 0 -- POP_MARK not available 5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(POP * (n+1) + get) 5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # No recursion. 5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(TUPLE) 5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[TupleType] = save_tuple 5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # save_empty_tuple() isn't used by anything in Python 2.3. However, I 5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # found a Pickler subclass in Zope3 that calls it, so it's not harmless 5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # to remove it. 5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_empty_tuple(self, obj): 5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write(EMPTY_TUPLE) 5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_list(self, obj): 5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(EMPTY_LIST) 5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: # proto 0 -- can't use EMPTY_LIST 5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK + LIST) 5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._batch_appends(iter(obj)) 6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[ListType] = save_list 6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Keep in synch with cPickle's BATCHSIZE. Nothing will break if it gets 6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # out of synch, though. 6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _BATCHSIZE = 1000 6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _batch_appends(self, items): 6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Helper to batch up APPENDS sequences 6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save = self.save 6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self.bin: 6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for x in items: 6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(x) 6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(APPEND) 6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = xrange(self._BATCHSIZE) 6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while items is not None: 6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tmp = [] 6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in r: 6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = items.next() 6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tmp.append(x) 6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except StopIteration: 6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm items = None 6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(tmp) 6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n > 1: 6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK) 6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for x in tmp: 6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(x) 6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(APPENDS) 6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif n: 6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(tmp[0]) 6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(APPEND) 6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # else tmp is empty, and we're done 6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_dict(self, obj): 6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(EMPTY_DICT) 6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: # proto 0 -- can't use EMPTY_DICT 6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK + DICT) 6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._batch_setitems(obj.iteritems()) 6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[DictionaryType] = save_dict 6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not PyStringMap is None: 6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[PyStringMap] = save_dict 6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _batch_setitems(self, items): 6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Helper to batch up SETITEMS sequences; proto >= 1 only 6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save = self.save 6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self.bin: 6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for k, v in items: 6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(k) 6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(v) 6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(SETITEM) 6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = xrange(self._BATCHSIZE) 6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while items is not None: 6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tmp = [] 6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in r: 6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tmp.append(items.next()) 6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except StopIteration: 6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm items = None 6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(tmp) 6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n > 1: 6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK) 6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for k, v in tmp: 6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(k) 6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(v) 6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(SETITEMS) 6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif n: 6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k, v = tmp[0] 6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(k) 6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(v) 6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(SETITEM) 6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # else tmp is empty, and we're done 6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_inst(self, obj): 6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cls = obj.__class__ 6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo = self.memo 6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save = self.save 6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(obj, '__getinitargs__'): 6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = obj.__getinitargs__() 6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm len(args) # XXX Assert it's a sequence 7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _keep_alive(args, memo) 7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = () 7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(MARK) 7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.bin: 7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(cls) 7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for arg in args: 7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(arg) 7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(OBJ) 7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for arg in args: 7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(arg) 7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') 7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm getstate = obj.__getstate__ 7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except AttributeError: 7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stuff = obj.__dict__ 7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stuff = getstate() 7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _keep_alive(stuff, memo) 7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm save(stuff) 7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(BUILD) 7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[InstanceType] = save_inst 7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def save_global(self, obj, name=None, pack=struct.pack): 7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write = self.write 7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo = self.memo 7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name is None: 7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = obj.__name__ 7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = getattr(obj, "__module__", None) 7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is None: 7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = whichmodule(obj, name) 7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __import__(module) 7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mod = sys.modules[module] 7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm klass = getattr(mod, name) 7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except (ImportError, KeyError, AttributeError): 7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError( 7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Can't pickle %r: it's not found as %s.%s" % 7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (obj, module, name)) 7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if klass is not obj: 7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise PicklingError( 7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Can't pickle %r: it's not the same object as %s.%s" % 7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (obj, module, name)) 7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.proto >= 2: 7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm code = _extension_registry.get((module, name)) 7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if code: 7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert code > 0 7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if code <= 0xff: 7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(EXT1 + chr(code)) 7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif code <= 0xffff: 7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write("%c%c%c" % (EXT2, code&0xff, code>>8)) 7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(EXT4 + pack("<i", code)) 7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm write(GLOBAL + module + '\n' + name + '\n') 7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memoize(obj) 7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[ClassType] = save_global 7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[FunctionType] = save_global 7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BuiltinFunctionType] = save_global 7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[TypeType] = save_global 7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Pickling helpers 7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _keep_alive(x, memo): 7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Keeps a reference to the object x in the memo. 7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Because we remember objects by their id, we have 7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to assure that possibly temporary objects are kept 7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm alive by referencing them. 7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm We store a reference at the id of the memo, which should 7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm normally not be used unless someone tries to deepcopy 7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the memo itself... 7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(memo)].append(x) 7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except KeyError: 7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # aha, this is the first one :-) 7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(memo)]=[x] 7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# A cache for whichmodule(), mapping a function object to the name of 7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# the module in which the function was found. 7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclassmap = {} # called classmap for backwards compatibility 7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef whichmodule(func, funcname): 8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Figure out the module in which a function occurs. 8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Search sys.modules for the module. 8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Cache in classmap. 8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return a module name. 8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If the function cannot be found, return "__main__". 8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Python functions should always get an __module__ from their globals. 8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mod = getattr(func, "__module__", None) 8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if mod is not None: 8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return mod 8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if func in classmap: 8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return classmap[func] 8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for name, module in sys.modules.items(): 8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if module is None: 8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm continue # skip dummy package entries 8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if name != '__main__' and getattr(module, funcname, None) is func: 8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = '__main__' 8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm classmap[func] = name 8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return name 8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Unpickling machinery 8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Unpickler: 8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, file): 8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """This takes a file-like object for reading a pickle data stream. 8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The protocol version of the pickle is detected automatically, so no 8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm proto argument is needed. 8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The file-like object must have two methods, a read() method that 8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm takes an integer argument, and a readline() method that requires no 8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm arguments. Both methods should return a string. Thus file-like 8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object can be a file object opened for reading, a StringIO object, 8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm or any other custom object that meets this interface. 8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.readline = file.readline 8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.read = file.read 8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo = {} 8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load(self): 8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Read a pickled object representation from the open file. 8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return the reconstituted object hierarchy specified in the file. 8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mark = object() # any new unique object 8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack = [] 8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append = self.stack.append 8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm read = self.read 8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch = self.dispatch 8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while 1: 8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm key = read(1) 8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[key](self) 8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except _Stop, stopinst: 8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return stopinst.value 8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Return largest index k such that self.stack[k] is self.mark. 8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If the stack doesn't contain a mark, eventually raises IndexError. 8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This could be sped by maintaining another stack, of indices at which 8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the mark appears. For that matter, the latter stack would suffice, 8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # and we wouldn't need to push mark objects on self.stack at all. 8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Doing so is probably a good thing, though, since if the pickle is 8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # corrupt (or hostile) we may get a clue from finding self.mark embedded 8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # in unpickled objects. 8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def marker(self): 8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mark = self.mark 8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k = len(stack)-1 8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while stack[k] is not mark: k = k-1 8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return k 8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch = {} 8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_eof(self): 8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise EOFError 8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[''] = load_eof 8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_proto(self): 8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm proto = ord(self.read(1)) 8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not 0 <= proto <= 2: 8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "unsupported pickle protocol: %d" % proto 8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[PROTO] = load_proto 8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_persid(self): 8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pid = self.readline()[:-1] 8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.persistent_load(pid)) 8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[PERSID] = load_persid 8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binpersid(self): 8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pid = self.stack.pop() 8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.persistent_load(pid)) 8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BINPERSID] = load_binpersid 8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_none(self): 9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(None) 9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[NONE] = load_none 9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_false(self): 9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(False) 9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[NEWFALSE] = load_false 9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_true(self): 9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(True) 9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[NEWTRUE] = load_true 9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_int(self): 9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm data = self.readline() 9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if data == FALSE[1:]: 9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = False 9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif data == TRUE[1:]: 9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = True 9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = int(data) 9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except ValueError: 9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = long(data) 9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(val) 9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[INT] = load_int 9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binint(self): 9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(mloads('i' + self.read(4))) 9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BININT] = load_binint 9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binint1(self): 9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(ord(self.read(1))) 9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BININT1] = load_binint1 9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binint2(self): 9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(mloads('i' + self.read(2) + '\000\000')) 9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BININT2] = load_binint2 9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_long(self): 9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(long(self.readline()[:-1], 0)) 9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LONG] = load_long 9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_long1(self): 9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = ord(self.read(1)) 9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bytes = self.read(n) 9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(decode_long(bytes)) 9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LONG1] = load_long1 9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_long4(self): 9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = mloads('i' + self.read(4)) 9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bytes = self.read(n) 9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(decode_long(bytes)) 9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LONG4] = load_long4 9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_float(self): 9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(float(self.readline()[:-1])) 9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[FLOAT] = load_float 9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binfloat(self, unpack=struct.unpack): 9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(unpack('>d', self.read(8))[0]) 9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BINFLOAT] = load_binfloat 9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_string(self): 9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rep = self.readline()[:-1] 9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for q in "\"'": # double or single quote 9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if rep.startswith(q): 9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not rep.endswith(q): 9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "insecure string pickle" 9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rep = rep[len(q):-len(q)] 9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "insecure string pickle" 9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(rep.decode("string-escape")) 9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[STRING] = load_string 9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binstring(self): 9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm len = mloads('i' + self.read(4)) 9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.read(len)) 9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BINSTRING] = load_binstring 9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_unicode(self): 9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(unicode(self.readline()[:-1],'raw-unicode-escape')) 9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[UNICODE] = load_unicode 9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binunicode(self): 9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm len = mloads('i' + self.read(4)) 9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(unicode(self.read(len),'utf-8')) 9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BINUNICODE] = load_binunicode 9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_short_binstring(self): 9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm len = ord(self.read(1)) 9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.read(len)) 9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[SHORT_BINSTRING] = load_short_binstring 9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_tuple(self): 9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k = self.marker() 9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[k:] = [tuple(self.stack[k+1:])] 9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[TUPLE] = load_tuple 9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_empty_tuple(self): 9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack.append(()) 10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[EMPTY_TUPLE] = load_empty_tuple 10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_tuple1(self): 10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[-1] = (self.stack[-1],) 10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[TUPLE1] = load_tuple1 10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_tuple2(self): 10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[-2:] = [(self.stack[-2], self.stack[-1])] 10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[TUPLE2] = load_tuple2 10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_tuple3(self): 10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])] 10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[TUPLE3] = load_tuple3 10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_empty_list(self): 10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack.append([]) 10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[EMPTY_LIST] = load_empty_list 10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_empty_dictionary(self): 10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack.append({}) 10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[EMPTY_DICT] = load_empty_dictionary 10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_list(self): 10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k = self.marker() 10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[k:] = [self.stack[k+1:]] 10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LIST] = load_list 10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_dict(self): 10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k = self.marker() 10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d = {} 10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm items = self.stack[k+1:] 10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in range(0, len(items), 2): 10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm key = items[i] 10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = items[i+1] 10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[key] = value 10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[k:] = [d] 10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[DICT] = load_dict 10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # INST and OBJ differ only in how they get a class object. It's not 10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # only sensible to do the rest in a common routine, the two routines 10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # previously diverged and grew different bugs. 10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # klass is the class to instantiate, and k points to the topmost mark 10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # object, following which are the arguments for klass.__init__. 10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _instantiate(self, klass, k): 10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = tuple(self.stack[k+1:]) 10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.stack[k:] 10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm instantiated = 0 10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (not args and 10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm type(klass) is ClassType and 10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm not hasattr(klass, "__getinitargs__")): 10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = _EmptyClass() 10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value.__class__ = klass 10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm instantiated = 1 10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except RuntimeError: 10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # In restricted execution, assignment to inst.__class__ is 10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # prohibited 10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not instantiated: 10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = klass(*args) 10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError, err: 10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError, "in constructor for %s: %s" % ( 10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm klass.__name__, str(err)), sys.exc_info()[2] 10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(value) 10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_inst(self): 10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = self.readline()[:-1] 10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = self.readline()[:-1] 10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm klass = self.find_class(module, name) 10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._instantiate(klass, self.marker()) 10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[INST] = load_inst 10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_obj(self): 10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Stack is ... markobject classobject arg1 arg2 ... 10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k = self.marker() 10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm klass = self.stack.pop(k+1) 10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._instantiate(klass, k) 10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[OBJ] = load_obj 10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_newobj(self): 10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = self.stack.pop() 10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cls = self.stack[-1] 10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = cls.__new__(cls, *args) 10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stack[-1] = obj 10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[NEWOBJ] = load_newobj 10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_global(self): 10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm module = self.readline()[:-1] 10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm name = self.readline()[:-1] 10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm klass = self.find_class(module, name) 10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(klass) 10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[GLOBAL] = load_global 10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_ext1(self): 10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm code = ord(self.read(1)) 10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.get_extension(code) 10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[EXT1] = load_ext1 10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_ext2(self): 11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm code = mloads('i' + self.read(2) + '\000\000') 11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.get_extension(code) 11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[EXT2] = load_ext2 11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_ext4(self): 11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm code = mloads('i' + self.read(4)) 11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.get_extension(code) 11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[EXT4] = load_ext4 11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def get_extension(self, code): 11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nil = [] 11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = _extension_cache.get(code, nil) 11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if obj is not nil: 11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(obj) 11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm key = _inverted_registry.get(code) 11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not key: 11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError("unregistered extension code %d" % code) 11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = self.find_class(*key) 11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _extension_cache[code] = obj 11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(obj) 11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def find_class(self, module, name): 11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Subclasses may override this 11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __import__(module) 11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mod = sys.modules[module] 11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm klass = getattr(mod, name) 11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return klass 11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_reduce(self): 11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = stack.pop() 11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm func = stack[-1] 11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = func(*args) 11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack[-1] = value 11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[REDUCE] = load_reduce 11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_pop(self): 11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.stack[-1] 11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[POP] = load_pop 11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_pop_mark(self): 11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm k = self.marker() 11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.stack[k:] 11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[POP_MARK] = load_pop_mark 11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_dup(self): 11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.stack[-1]) 11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[DUP] = load_dup 11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_get(self): 11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.memo[self.readline()[:-1]]) 11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[GET] = load_get 11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binget(self): 11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm i = ord(self.read(1)) 11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.memo[repr(i)]) 11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BINGET] = load_binget 11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_long_binget(self): 11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm i = mloads('i' + self.read(4)) 11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.memo[repr(i)]) 11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LONG_BINGET] = load_long_binget 11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_put(self): 11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo[self.readline()[:-1]] = self.stack[-1] 11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[PUT] = load_put 11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_binput(self): 11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm i = ord(self.read(1)) 11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo[repr(i)] = self.stack[-1] 11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BINPUT] = load_binput 11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_long_binput(self): 11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm i = mloads('i' + self.read(4)) 11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.memo[repr(i)] = self.stack[-1] 11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[LONG_BINPUT] = load_long_binput 11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_append(self): 11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = stack.pop() 11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list = stack[-1] 11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list.append(value) 11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[APPEND] = load_append 11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_appends(self): 11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mark = self.marker() 11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list = stack[mark - 1] 11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list.extend(stack[mark + 1:]) 11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del stack[mark:] 11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[APPENDS] = load_appends 11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_setitem(self): 11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = stack.pop() 11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm key = stack.pop() 11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict = stack[-1] 11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict[key] = value 11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[SETITEM] = load_setitem 12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_setitems(self): 12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mark = self.marker() 12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict = stack[mark - 1] 12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in range(mark + 1, len(stack), 2): 12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict[stack[i]] = stack[i + 1] 12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del stack[mark:] 12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[SETITEMS] = load_setitems 12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_build(self): 12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stack = self.stack 12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = stack.pop() 12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inst = stack[-1] 12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setstate = getattr(inst, "__setstate__", None) 12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if setstate: 12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setstate(state) 12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm slotstate = None 12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(state, tuple) and len(state) == 2: 12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state, slotstate = state 12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if state: 12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d = inst.__dict__ 12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for k, v in state.iteritems(): 12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[intern(k)] = v 12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # keys in state don't have to be strings 12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # don't blow up, but don't go out of our way 12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError: 12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d.update(state) 12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except RuntimeError: 12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # XXX In restricted execution, the instance's __dict__ 12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # is not accessible. Use the old way of unpickling 12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the instance variables. This is a semantic 12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # difference when unpickling in restricted 12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # vs. unrestricted modes. 12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Note, however, that cPickle has never tried to do the 12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # .update() business, and always uses 12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # PyObject_SetItem(inst.__dict__, key, value) in a 12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # loop over state.items(). 12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for k, v in state.items(): 12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setattr(inst, k, v) 12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if slotstate: 12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for k, v in slotstate.items(): 12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setattr(inst, k, v) 12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[BUILD] = load_build 12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_mark(self): 12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.append(self.mark) 12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[MARK] = load_mark 12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def load_stop(self): 12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = self.stack.pop() 12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise _Stop(value) 12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dispatch[STOP] = load_stop 12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Helper class for load_inst/load_obj 12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass _EmptyClass: 12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Encode/decode longs in linear time. 12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport binascii as _binascii 12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef encode_long(x): 12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r"""Encode a long to a two's complement little-endian binary string. 12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Note that 0L is a special case, returning an empty string, to save a 12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm byte in the LONG1 pickling context. 12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(0L) 12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '' 12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(255L) 12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '\xff\x00' 12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(32767L) 12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '\xff\x7f' 12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(-256L) 12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '\x00\xff' 12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(-32768L) 12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '\x00\x80' 12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(-128L) 12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '\x80' 12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> encode_long(127L) 12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '\x7f' 12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> 12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if x == 0: 12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return '' 12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if x > 0: 12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = hex(x) 12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert ashex.startswith("0x") 12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm njunkchars = 2 + ashex.endswith('L') 12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nibbles = len(ashex) - njunkchars 12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if nibbles & 1: 12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # need an even # of nibbles for unhexlify 12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = "0x0" + ashex[2:] 13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif int(ashex[2], 16) >= 8: 13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # "looks negative", so need a byte of sign bits 13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = "0x00" + ashex[2:] 13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Build the 256's-complement: (1L << nbytes) + x. The trick is 13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # to find the number of bytes in linear time (although that should 13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # really be a constant-time task). 13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = hex(-x) 13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert ashex.startswith("0x") 13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm njunkchars = 2 + ashex.endswith('L') 13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nibbles = len(ashex) - njunkchars 13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if nibbles & 1: 13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Extend to a full byte. 13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nibbles += 1 13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nbits = nibbles * 4 13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x += 1L << nbits 13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert x > 0 13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = hex(x) 13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm njunkchars = 2 + ashex.endswith('L') 13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newnibbles = len(ashex) - njunkchars 13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if newnibbles < nibbles: 13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = "0x" + "0" * (nibbles - newnibbles) + ashex[2:] 13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if int(ashex[2], 16) < 8: 13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # "looks positive", so need a byte of sign bits 13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = "0xff" + ashex[2:] 13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ashex.endswith('L'): 13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = ashex[2:-1] 13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = ashex[2:] 13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert len(ashex) & 1 == 0, (x, ashex) 13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm binary = _binascii.unhexlify(ashex) 13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return binary[::-1] 13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef decode_long(data): 13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r"""Decode a long from a two's complement little-endian binary string. 13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long('') 13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0L 13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long("\xff\x00") 13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 255L 13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long("\xff\x7f") 13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 32767L 13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long("\x00\xff") 13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm -256L 13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long("\x00\x80") 13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm -32768L 13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long("\x80") 13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm -128L 13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm >>> decode_long("\x7f") 13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 127L 13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nbytes = len(data) 13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if nbytes == 0: 13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0L 13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ashex = _binascii.hexlify(data[::-1]) 13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = long(ashex, 16) # quadratic time before Python 2.3; linear now 13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if data[-1] >= '\x80': 13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n -= 1L << (nbytes * 8) 13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return n 13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Shorthands 13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from cStringIO import StringIO 13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept ImportError: 13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from StringIO import StringIO 13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef dump(obj, file, protocol=None): 13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Pickler(file, protocol).dump(obj) 13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef dumps(obj, protocol=None): 13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = StringIO() 13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Pickler(file, protocol).dump(obj) 13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return file.getvalue() 13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef load(file): 13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Unpickler(file).load() 13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef loads(str): 13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = StringIO(str) 13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Unpickler(file).load() 13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Doctest 13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _test(): 13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import doctest 13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return doctest.testmod() 13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__": 13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _test() 1392