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