home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_Lib_pickle.py < prev    next >
Encoding:
Python Source  |  2001-07-26  |  26.9 KB  |  987 lines

  1. """Create portable serialized representations of Python objects.
  2.  
  3. See module cPickle for a (much) faster implementation.
  4. See module copy_reg for a mechanism for registering custom picklers.
  5.  
  6. Classes:
  7.  
  8.     Pickler
  9.     Unpickler
  10.  
  11. Functions:
  12.  
  13.     dump(object, file)
  14.     dumps(object) -> string
  15.     load(file) -> object
  16.     loads(string) -> object
  17.  
  18. Misc variables:
  19.  
  20.     __version__
  21.     format_version
  22.     compatible_formats
  23.  
  24. """
  25.  
  26. __version__ = "$Revision: 1.48 $"       # Code version
  27.  
  28. from types import *
  29. from copy_reg import dispatch_table, safe_constructors
  30. import marshal
  31. import sys
  32. import struct
  33. import re
  34.  
  35. __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
  36.            "Unpickler", "dump", "dumps", "load", "loads"]
  37.  
  38. format_version = "1.3"                     # File format version we write
  39. compatible_formats = ["1.0", "1.1", "1.2"] # Old format versions we can read
  40.  
  41. mdumps = marshal.dumps
  42. mloads = marshal.loads
  43.  
  44. class PickleError(Exception): pass
  45. class PicklingError(PickleError): pass
  46. class UnpicklingError(PickleError): pass
  47.  
  48. class _Stop(Exception):
  49.     def __init__(self, value):
  50.         self.value = value
  51.  
  52. try:
  53.     from org.python.core import PyStringMap
  54. except ImportError:
  55.     PyStringMap = None
  56.  
  57. MARK            = '('
  58. STOP            = '.'
  59. POP             = '0'
  60. POP_MARK        = '1'
  61. DUP             = '2'
  62. FLOAT           = 'F'
  63. INT             = 'I'
  64. BININT          = 'J'
  65. BININT1         = 'K'
  66. LONG            = 'L'
  67. BININT2         = 'M'
  68. NONE            = 'N'
  69. PERSID          = 'P'
  70. BINPERSID       = 'Q'
  71. REDUCE          = 'R'
  72. STRING          = 'S'
  73. BINSTRING       = 'T'
  74. SHORT_BINSTRING = 'U'
  75. UNICODE         = 'V'
  76. BINUNICODE      = 'X'
  77. APPEND          = 'a'
  78. BUILD           = 'b'
  79. GLOBAL          = 'c'
  80. DICT            = 'd'
  81. EMPTY_DICT      = '}'
  82. APPENDS         = 'e'
  83. GET             = 'g'
  84. BINGET          = 'h'
  85. INST            = 'i'
  86. LONG_BINGET     = 'j'
  87. LIST            = 'l'
  88. EMPTY_LIST      = ']'
  89. OBJ             = 'o'
  90. PUT             = 'p'
  91. BINPUT          = 'q'
  92. LONG_BINPUT     = 'r'
  93. SETITEM         = 's'
  94. TUPLE           = 't'
  95. EMPTY_TUPLE     = ')'
  96. SETITEMS        = 'u'
  97. BINFLOAT        = 'G'
  98.  
  99. __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)])
  100.  
  101. class Pickler:
  102.  
  103.     def __init__(self, file, bin = 0):
  104.         self.write = file.write
  105.         self.memo = {}
  106.         self.bin = bin
  107.  
  108.     def dump(self, object):
  109.         self.save(object)
  110.         self.write(STOP)
  111.  
  112.     def put(self, i):
  113.         if self.bin:
  114.             s = mdumps(i)[1:]
  115.             if i < 256:
  116.                 return BINPUT + s[0]
  117.  
  118.             return LONG_BINPUT + s
  119.  
  120.         return PUT + `i` + '\n'
  121.  
  122.     def get(self, i):
  123.         if self.bin:
  124.             s = mdumps(i)[1:]
  125.  
  126.             if i < 256:
  127.                 return BINGET + s[0]
  128.  
  129.             return LONG_BINGET + s
  130.  
  131.         return GET + `i` + '\n'
  132.  
  133.     def save(self, object, pers_save = 0):
  134.         memo = self.memo
  135.  
  136.         if not pers_save:
  137.             pid = self.persistent_id(object)
  138.             if pid is not None:
  139.                 self.save_pers(pid)
  140.                 return
  141.  
  142.         d = id(object)
  143.  
  144.         t = type(object)
  145.  
  146.         if (t is TupleType) and (len(object) == 0):
  147.             if self.bin:
  148.                 self.save_empty_tuple(object)
  149.             else:
  150.                 self.save_tuple(object)
  151.             return
  152.  
  153.         if memo.has_key(d):
  154.             self.write(self.get(memo[d][0]))
  155.             return
  156.  
  157.         try:
  158.             f = self.dispatch[t]
  159.         except KeyError:
  160.             pid = self.inst_persistent_id(object)
  161.             if pid is not None:
  162.                 self.save_pers(pid)
  163.                 return
  164.  
  165.             try:
  166.                 reduce = dispatch_table[t]
  167.             except KeyError:
  168.                 try:
  169.                     reduce = object.__reduce__
  170.                 except AttributeError:
  171.                     raise PicklingError, \
  172.                         "can't pickle %s object: %s" % (`t.__name__`,
  173.                                                          `object`)
  174.                 else:
  175.                     tup = reduce()
  176.             else:
  177.                 tup = reduce(object)
  178.  
  179.             if type(tup) is StringType:
  180.                 self.save_global(object, tup)
  181.                 return
  182.  
  183.             if type(tup) is not TupleType:
  184.                 raise PicklingError, "Value returned by %s must be a " \
  185.                                      "tuple" % reduce
  186.  
  187.             l = len(tup)
  188.  
  189.             if (l != 2) and (l != 3):
  190.                 raise PicklingError, "tuple returned by %s must contain " \
  191.                                      "only two or three elements" % reduce
  192.  
  193.             callable = tup[0]
  194.             arg_tup  = tup[1]
  195.  
  196.             if l > 2:
  197.                 state = tup[2]
  198.             else:
  199.                 state = None
  200.  
  201.             if type(arg_tup) is not TupleType and arg_tup is not None:
  202.                 raise PicklingError, "Second element of tuple returned " \
  203.                                      "by %s must be a tuple" % reduce
  204.  
  205.             self.save_reduce(callable, arg_tup, state)
  206.             memo_len = len(memo)
  207.             self.write(self.put(memo_len))
  208.             memo[d] = (memo_len, object)
  209.             return
  210.  
  211.         f(self, object)
  212.  
  213.     def persistent_id(self, object):
  214.         return None
  215.  
  216.     def inst_persistent_id(self, object):
  217.         return None
  218.  
  219.     def save_pers(self, pid):
  220.         if not self.bin:
  221.             self.write(PERSID + str(pid) + '\n')
  222.         else:
  223.             self.save(pid, 1)
  224.             self.write(BINPERSID)
  225.  
  226.     def save_reduce(self, callable, arg_tup, state = None):
  227.         write = self.write
  228.         save = self.save
  229.  
  230.         save(callable)
  231.         save(arg_tup)
  232.         write(REDUCE)
  233.  
  234.         if state is not None:
  235.             save(state)
  236.             write(BUILD)
  237.  
  238.     dispatch = {}
  239.  
  240.     def save_none(self, object):
  241.         self.write(NONE)
  242.     dispatch[NoneType] = save_none
  243.  
  244.     def save_int(self, object):
  245.         if self.bin:
  246.             # If the int is small enough to fit in a signed 4-byte 2's-comp
  247.             # format, we can store it more efficiently than the general
  248.             # case.
  249.             high_bits = object >> 31  # note that Python shift sign-extends
  250.             if  high_bits == 0 or high_bits == -1:
  251.                 # All high bits are copies of bit 2**31, so the value
  252.                 # fits in a 4-byte signed int.
  253.                 i = mdumps(object)[1:]
  254.                 assert len(i) == 4
  255.                 if i[-2:] == '\000\000':    # fits in 2-byte unsigned int
  256.                     if i[-3] == '\000':     # fits in 1-byte unsigned int
  257.                         self.write(BININT1 + i[0])
  258.                     else:
  259.                         self.write(BININT2 + i[:2])
  260.                 else:
  261.                     self.write(BININT + i)
  262.                 return
  263.         # Text pickle, or int too big to fit in signed 4-byte format.
  264.         self.write(INT + `object` + '\n')
  265.     dispatch[IntType] = save_int
  266.  
  267.     def save_long(self, object):
  268.         self.write(LONG + `object` + '\n')
  269.     dispatch[LongType] = save_long
  270.  
  271.     def save_float(self, object, pack=struct.pack):
  272.         if self.bin:
  273.             self.write(BINFLOAT + pack('>d', object))
  274.         else:
  275.             self.write(FLOAT + `object` + '\n')
  276.     dispatch[FloatType] = save_float
  277.  
  278.     def save_string(self, object):
  279.         d = id(object)
  280.         memo = self.memo
  281.  
  282.         if self.bin:
  283.             l = len(object)
  284.             s = mdumps(l)[1:]
  285.             if l < 256:
  286.                 self.write(SHORT_BINSTRING + s[0] + object)
  287.             else:
  288.                 self.write(BINSTRING + s + object)
  289.         else:
  290.             self.write(STRING + `object` + '\n')
  291.  
  292.         memo_len = len(memo)
  293.         self.write(self.put(memo_len))
  294.         memo[d] = (memo_len, object)
  295.     dispatch[StringType] = save_string
  296.  
  297.     def save_unicode(self, object):
  298.         d = id(object)
  299.         memo = self.memo
  300.  
  301.         if self.bin:
  302.             encoding = object.encode('utf-8')
  303.             l = len(encoding)
  304.             s = mdumps(l)[1:]
  305.             self.write(BINUNICODE + s + encoding)
  306.         else:
  307.             object = object.replace(u"\\", u"\\u005c")
  308.             object = object.replace(u"\n", u"\\u000a")
  309.             self.write(UNICODE + object.encode('raw-unicode-escape') + '\n')
  310.  
  311.         memo_len = len(memo)
  312.         self.write(self.put(memo_len))
  313.         memo[d] = (memo_len, object)
  314.     dispatch[UnicodeType] = save_unicode
  315.  
  316.     if StringType == UnicodeType:
  317.         # This is true for Jython
  318.         def save_string(self, object):
  319.             d = id(object)
  320.             memo = self.memo
  321.             unicode = object.isunicode()
  322.  
  323.             if self.bin:
  324.                 if unicode:
  325.                     object = object.encode("utf-8")
  326.                 l = len(object)
  327.                 s = mdumps(l)[1:]
  328.                 if l < 256 and not unicode:
  329.                     self.write(SHORT_BINSTRING + s[0] + object)
  330.                 else:
  331.                     if unicode:
  332.                         self.write(BINUNICODE + s + object)
  333.                     else:
  334.                         self.write(BINSTRING + s + object)
  335.             else:
  336.                 if unicode:
  337.                     object = object.replace(u"\\", u"\\u005c")
  338.                     object = object.replace(u"\n", u"\\u000a")
  339.                     object = object.encode('raw-unicode-escape')
  340.                     self.write(UNICODE + object + '\n')
  341.                 else:
  342.                     self.write(STRING + `object` + '\n')
  343.  
  344.             memo_len = len(memo)
  345.             self.write(self.put(memo_len))
  346.             memo[d] = (memo_len, object)
  347.         dispatch[StringType] = save_string
  348.  
  349.     def save_tuple(self, object):
  350.  
  351.         write = self.write
  352.         save  = self.save
  353.         memo  = self.memo
  354.  
  355.         d = id(object)
  356.  
  357.         write(MARK)
  358.  
  359.         for element in object:
  360.             save(element)
  361.  
  362.         if len(object) and memo.has_key(d):
  363.             if self.bin:
  364.                 write(POP_MARK + self.get(memo[d][0]))
  365.                 return
  366.  
  367.             write(POP * (len(object) + 1) + self.get(memo[d][0]))
  368.             return
  369.  
  370.         memo_len = len(memo)
  371.         self.write(TUPLE + self.put(memo_len))
  372.         memo[d] = (memo_len, object)
  373.     dispatch[TupleType] = save_tuple
  374.  
  375.     def save_empty_tuple(self, object):
  376.         self.write(EMPTY_TUPLE)
  377.  
  378.     def save_list(self, object):
  379.         d = id(object)
  380.  
  381.         write = self.write
  382.         save  = self.save
  383.         memo  = self.memo
  384.  
  385.         if self.bin:
  386.             write(EMPTY_LIST)
  387.         else:
  388.             write(MARK + LIST)
  389.  
  390.         memo_len = len(memo)
  391.         write(self.put(memo_len))
  392.         memo[d] = (memo_len, object)
  393.  
  394.         using_appends = (self.bin and (len(object) > 1))
  395.  
  396.         if using_appends:
  397.             write(MARK)
  398.  
  399.         for element in object:
  400.             save(element)
  401.  
  402.             if not using_appends:
  403.                 write(APPEND)
  404.  
  405.         if using_appends:
  406.             write(APPENDS)
  407.     dispatch[ListType] = save_list
  408.  
  409.     def save_dict(self, object):
  410.         d = id(object)
  411.  
  412.         write = self.write
  413.         save  = self.save
  414.         memo  = self.memo
  415.  
  416.         if self.bin:
  417.             write(EMPTY_DICT)
  418.         else:
  419.             write(MARK + DICT)
  420.  
  421.         memo_len = len(memo)
  422.         self.write(self.put(memo_len))
  423.         memo[d] = (memo_len, object)
  424.  
  425.         using_setitems = (self.bin and (len(object) > 1))
  426.  
  427.         if using_setitems:
  428.             write(MARK)
  429.  
  430.         items = object.items()
  431.         for key, value in items:
  432.             save(key)
  433.             save(value)
  434.  
  435.             if not using_setitems:
  436.                 write(SETITEM)
  437.  
  438.         if using_setitems:
  439.             write(SETITEMS)
  440.  
  441.     dispatch[DictionaryType] = save_dict
  442.     if not PyStringMap is None:
  443.         dispatch[PyStringMap] = save_dict
  444.  
  445.     def save_inst(self, object):
  446.         d = id(object)
  447.         cls = object.__class__
  448.  
  449.         memo  = self.memo
  450.         write = self.write
  451.         save  = self.save
  452.  
  453.         if hasattr(object, '__getinitargs__'):
  454.             args = object.__getinitargs__()
  455.             len(args) # XXX Assert it's a sequence
  456.             _keep_alive(args, memo)
  457.         else:
  458.             args = ()
  459.  
  460.         write(MARK)
  461.  
  462.         if self.bin:
  463.             save(cls)
  464.  
  465.         for arg in args:
  466.             save(arg)
  467.  
  468.         memo_len = len(memo)
  469.         if self.bin:
  470.             write(OBJ + self.put(memo_len))
  471.         else:
  472.             write(INST + cls.__module__ + '\n' + cls.__name__ + '\n' +
  473.                 self.put(memo_len))
  474.  
  475.         memo[d] = (memo_len, object)
  476.  
  477.         try:
  478.             getstate = object.__getstate__
  479.         except AttributeError:
  480.             stuff = object.__dict__
  481.         else:
  482.             stuff = getstate()
  483.             _keep_alive(stuff, memo)
  484.         save(stuff)
  485.         write(BUILD)
  486.     dispatch[InstanceType] = save_inst
  487.  
  488.     def save_global(self, object, name = None):
  489.         write = self.write
  490.         memo = self.memo
  491.  
  492.         if name is None:
  493.             name = object.__name__
  494.  
  495.         try:
  496.             module = object.__module__
  497.         except AttributeError:
  498.             module = whichmodule(object, name)
  499.  
  500.         memo_len = len(memo)
  501.         write(GLOBAL + module + '\n' + name + '\n' +
  502.             self.put(memo_len))
  503.         memo[id(object)] = (memo_len, object)
  504.     dispatch[ClassType] = save_global
  505.     dispatch[FunctionType] = save_global
  506.     dispatch[BuiltinFunctionType] = save_global
  507.  
  508.  
  509. def _keep_alive(x, memo):
  510.     """Keeps a reference to the object x in the memo.
  511.  
  512.     Because we remember objects by their id, we have
  513.     to assure that possibly temporary objects are kept
  514.     alive by referencing them.
  515.     We store a reference at the id of the memo, which should
  516.     normally not be used unless someone tries to deepcopy
  517.     the memo itself...
  518.     """
  519.     try:
  520.         memo[id(memo)].append(x)
  521.     except KeyError:
  522.         # aha, this is the first one :-)
  523.         memo[id(memo)]=[x]
  524.  
  525.  
  526. classmap = {}
  527.  
  528. # This is no longer used to find classes, but still for functions
  529. def whichmodule(cls, clsname):
  530.     """Figure out the module in which a class occurs.
  531.  
  532.     Search sys.modules for the module.
  533.     Cache in classmap.
  534.     Return a module name.
  535.     If the class cannot be found, return __main__.
  536.     """
  537.     if classmap.has_key(cls):
  538.         return classmap[cls]
  539.  
  540.     for name, module in sys.modules.items():
  541.         if name != '__main__' and \
  542.             hasattr(module, clsname) and \
  543.             getattr(module, clsname) is cls:
  544.             break
  545.     else:
  546.         name = '__main__'
  547.     classmap[cls] = name
  548.     return name
  549.  
  550.  
  551. class Unpickler:
  552.  
  553.     def __init__(self, file):
  554.         self.readline = file.readline
  555.         self.read = file.read
  556.         self.memo = {}
  557.  
  558.     def load(self):
  559.         self.mark = ['spam'] # Any new unique object
  560.         self.stack = []
  561.         self.append = self.stack.append
  562.         read = self.read
  563.         dispatch = self.dispatch
  564.         try:
  565.             while 1:
  566.                 key = read(1)
  567.                 dispatch[key](self)
  568.         except _Stop, stopinst:
  569.             return stopinst.value
  570.  
  571.     def marker(self):
  572.         stack = self.stack
  573.         mark = self.mark
  574.         k = len(stack)-1
  575.         while stack[k] is not mark: k = k-1
  576.         return k
  577.  
  578.     dispatch = {}
  579.  
  580.     def load_eof(self):
  581.         raise EOFError
  582.     dispatch[''] = load_eof
  583.  
  584.     def load_persid(self):
  585.         pid = self.readline()[:-1]
  586.         self.append(self.persistent_load(pid))
  587.     dispatch[PERSID] = load_persid
  588.  
  589.     def load_binpersid(self):
  590.         stack = self.stack
  591.  
  592.         pid = stack[-1]
  593.         del stack[-1]
  594.  
  595.         self.append(self.persistent_load(pid))
  596.     dispatch[BINPERSID] = load_binpersid
  597.  
  598.     def load_none(self):
  599.         self.append(None)
  600.     dispatch[NONE] = load_none
  601.  
  602.     def load_int(self):
  603.         self.append(int(self.readline()[:-1]))
  604.     dispatch[INT] = load_int
  605.  
  606.     def load_binint(self):
  607.         self.append(mloads('i' + self.read(4)))
  608.     dispatch[BININT] = load_binint
  609.  
  610.     def load_binint1(self):
  611.         self.append(mloads('i' + self.read(1) + '\000\000\000'))
  612.     dispatch[BININT1] = load_binint1
  613.  
  614.     def load_binint2(self):
  615.         self.append(mloads('i' + self.read(2) + '\000\000'))
  616.     dispatch[BININT2] = load_binint2
  617.  
  618.     def load_long(self):
  619.         self.append(long(self.readline()[:-1], 0))
  620.     dispatch[LONG] = load_long
  621.  
  622.     def load_float(self):
  623.         self.append(float(self.readline()[:-1]))
  624.     dispatch[FLOAT] = load_float
  625.  
  626.     def load_binfloat(self, unpack=struct.unpack):
  627.         self.append(unpack('>d', self.read(8))[0])
  628.     dispatch[BINFLOAT] = load_binfloat
  629.  
  630.     def load_string(self):
  631.         rep = self.readline()[:-1]
  632.         if not self._is_string_secure(rep):
  633.             raise ValueError, "insecure string pickle"
  634.         self.append(eval(rep,
  635.                          {'__builtins__': {}})) # Let's be careful
  636.     dispatch[STRING] = load_string
  637.  
  638.     def _is_string_secure(self, s):
  639.         """Return true if s contains a string that is safe to eval
  640.  
  641.         The definition of secure string is based on the implementation
  642.         in cPickle.  s is secure as long as it only contains a quoted
  643.         string and optional trailing whitespace.
  644.         """
  645.         q = s[0]
  646.         if q not in ("'", '"'):
  647.             return 0
  648.         # find the closing quote
  649.         offset = 1
  650.         i = None
  651.         while 1:
  652.             try:
  653.                 i = s.index(q, offset)
  654.             except ValueError:
  655.                 # if there is an error the first time, there is no
  656.                 # close quote
  657.                 if offset == 1:
  658.                     return 0
  659.             if s[i-1] != '\\':
  660.                 break
  661.             # check to see if this one is escaped
  662.             nslash = 0
  663.             j = i - 1
  664.             while j >= offset and s[j] == '\\':
  665.                 j = j - 1
  666.                 nslash = nslash + 1
  667.             if nslash % 2 == 0:
  668.                 break
  669.             offset = i + 1
  670.         for c in s[i+1:]:
  671.             if ord(c) > 32:
  672.                 return 0
  673.         return 1
  674.  
  675.     def load_binstring(self):
  676.         len = mloads('i' + self.read(4))
  677.         self.append(self.read(len))
  678.     dispatch[BINSTRING] = load_binstring
  679.  
  680.     def load_unicode(self):
  681.         self.append(unicode(self.readline()[:-1],'raw-unicode-escape'))
  682.     dispatch[UNICODE] = load_unicode
  683.  
  684.     def load_binunicode(self):
  685.         len = mloads('i' + self.read(4))
  686.         self.append(unicode(self.read(len),'utf-8'))
  687.     dispatch[BINUNICODE] = load_binunicode
  688.  
  689.     def load_short_binstring(self):
  690.         len = mloads('i' + self.read(1) + '\000\000\000')
  691.         self.append(self.read(len))
  692.     dispatch[SHORT_BINSTRING] = load_short_binstring
  693.  
  694.     def load_tuple(self):
  695.         k = self.marker()
  696.         self.stack[k:] = [tuple(self.stack[k+1:])]
  697.     dispatch[TUPLE] = load_tuple
  698.  
  699.     def load_empty_tuple(self):
  700.         self.stack.append(())
  701.     dispatch[EMPTY_TUPLE] = load_empty_tuple
  702.  
  703.     def load_empty_list(self):
  704.         self.stack.append([])
  705.     dispatch[EMPTY_LIST] = load_empty_list
  706.  
  707.     def load_empty_dictionary(self):
  708.         self.stack.append({})
  709.     dispatch[EMPTY_DICT] = load_empty_dictionary
  710.  
  711.     def load_list(self):
  712.         k = self.marker()
  713.         self.stack[k:] = [self.stack[k+1:]]
  714.     dispatch[LIST] = load_list
  715.  
  716.     def load_dict(self):
  717.         k = self.marker()
  718.         d = {}
  719.         items = self.stack[k+1:]
  720.         for i in range(0, len(items), 2):
  721.             key = items[i]
  722.             value = items[i+1]
  723.             d[key] = value
  724.         self.stack[k:] = [d]
  725.     dispatch[DICT] = load_dict
  726.  
  727.     def load_inst(self):
  728.         k = self.marker()
  729.         args = tuple(self.stack[k+1:])
  730.         del self.stack[k:]
  731.         module = self.readline()[:-1]
  732.         name = self.readline()[:-1]
  733.         klass = self.find_class(module, name)
  734.         instantiated = 0
  735.         if (not args and type(klass) is ClassType and
  736.             not hasattr(klass, "__getinitargs__")):
  737.             try:
  738.                 value = _EmptyClass()
  739.                 value.__class__ = klass
  740.                 instantiated = 1
  741.             except RuntimeError:
  742.                 # In restricted execution, assignment to inst.__class__ is
  743.                 # prohibited
  744.                 pass
  745.         if not instantiated:
  746.             try:
  747.                 value = apply(klass, args)
  748.             except TypeError, err:
  749.                 raise TypeError, "in constructor for %s: %s" % (
  750.                     klass.__name__, str(err)), sys.exc_info()[2]
  751.         self.append(value)
  752.     dispatch[INST] = load_inst
  753.  
  754.     def load_obj(self):
  755.         stack = self.stack
  756.         k = self.marker()
  757.         klass = stack[k + 1]
  758.         del stack[k + 1]
  759.         args = tuple(stack[k + 1:])
  760.         del stack[k:]
  761.         instantiated = 0
  762.         if (not args and type(klass) is ClassType and
  763.             not hasattr(klass, "__getinitargs__")):
  764.             try:
  765.                 value = _EmptyClass()
  766.                 value.__class__ = klass
  767.                 instantiated = 1
  768.             except RuntimeError:
  769.                 # In restricted execution, assignment to inst.__class__ is
  770.                 # prohibited
  771.                 pass
  772.         if not instantiated:
  773.             value = apply(klass, args)
  774.         self.append(value)
  775.     dispatch[OBJ] = load_obj
  776.  
  777.     def load_global(self):
  778.         module = self.readline()[:-1]
  779.         name = self.readline()[:-1]
  780.         klass = self.find_class(module, name)
  781.         self.append(klass)
  782.     dispatch[GLOBAL] = load_global
  783.  
  784.     def find_class(self, module, name):
  785.         try:
  786.             __import__(module)
  787.             mod = sys.modules[module]
  788.             klass = getattr(mod, name)
  789.         except (ImportError, KeyError, AttributeError):
  790.             raise SystemError, \
  791.                   "Failed to import class %s from module %s" % \
  792.                   (name, module)
  793.         return klass
  794.  
  795.     def load_reduce(self):
  796.         stack = self.stack
  797.  
  798.         callable = stack[-2]
  799.         arg_tup  = stack[-1]
  800.         del stack[-2:]
  801.  
  802.         if type(callable) is not ClassType:
  803.             if not safe_constructors.has_key(callable):
  804.                 try:
  805.                     safe = callable.__safe_for_unpickling__
  806.                 except AttributeError:
  807.                     safe = None
  808.  
  809.                 if not safe:
  810.                     raise UnpicklingError, "%s is not safe for " \
  811.                                            "unpickling" % callable
  812.  
  813.         if arg_tup is None:
  814.             value = callable.__basicnew__()
  815.         else:
  816.             value = apply(callable, arg_tup)
  817.         self.append(value)
  818.     dispatch[REDUCE] = load_reduce
  819.  
  820.     def load_pop(self):
  821.         del self.stack[-1]
  822.     dispatch[POP] = load_pop
  823.  
  824.     def load_pop_mark(self):
  825.         k = self.marker()
  826.         del self.stack[k:]
  827.     dispatch[POP_MARK] = load_pop_mark
  828.  
  829.     def load_dup(self):
  830.         self.append(self.stack[-1])
  831.     dispatch[DUP] = load_dup
  832.  
  833.     def load_get(self):
  834.         self.append(self.memo[self.readline()[:-1]])
  835.     dispatch[GET] = load_get
  836.  
  837.     def load_binget(self):
  838.         i = mloads('i' + self.read(1) + '\000\000\000')
  839.         self.append(self.memo[`i`])
  840.     dispatch[BINGET] = load_binget
  841.  
  842.     def load_long_binget(self):
  843.         i = mloads('i' + self.read(4))
  844.         self.append(self.memo[`i`])
  845.     dispatch[LONG_BINGET] = load_long_binget
  846.  
  847.     def load_put(self):
  848.         self.memo[self.readline()[:-1]] = self.stack[-1]
  849.     dispatch[PUT] = load_put
  850.  
  851.     def load_binput(self):
  852.         i = mloads('i' + self.read(1) + '\000\000\000')
  853.         self.memo[`i`] = self.stack[-1]
  854.     dispatch[BINPUT] = load_binput
  855.  
  856.     def load_long_binput(self):
  857.         i = mloads('i' + self.read(4))
  858.         self.memo[`i`] = self.stack[-1]
  859.     dispatch[LONG_BINPUT] = load_long_binput
  860.  
  861.     def load_append(self):
  862.         stack = self.stack
  863.         value = stack[-1]
  864.         del stack[-1]
  865.         list = stack[-1]
  866.         list.append(value)
  867.     dispatch[APPEND] = load_append
  868.  
  869.     def load_appends(self):
  870.         stack = self.stack
  871.         mark = self.marker()
  872.         list = stack[mark - 1]
  873.         for i in range(mark + 1, len(stack)):
  874.             list.append(stack[i])
  875.  
  876.         del stack[mark:]
  877.     dispatch[APPENDS] = load_appends
  878.  
  879.     def load_setitem(self):
  880.         stack = self.stack
  881.         value = stack[-1]
  882.         key = stack[-2]
  883.         del stack[-2:]
  884.         dict = stack[-1]
  885.         dict[key] = value
  886.     dispatch[SETITEM] = load_setitem
  887.  
  888.     def load_setitems(self):
  889.         stack = self.stack
  890.         mark = self.marker()
  891.         dict = stack[mark - 1]
  892.         for i in range(mark + 1, len(stack), 2):
  893.             dict[stack[i]] = stack[i + 1]
  894.  
  895.         del stack[mark:]
  896.     dispatch[SETITEMS] = load_setitems
  897.  
  898.     def load_build(self):
  899.         stack = self.stack
  900.         value = stack[-1]
  901.         del stack[-1]
  902.         inst = stack[-1]
  903.         try:
  904.             setstate = inst.__setstate__
  905.         except AttributeError:
  906.             try:
  907.                 inst.__dict__.update(value)
  908.             except RuntimeError:
  909.                 # XXX In restricted execution, the instance's __dict__ is not
  910.                 # accessible.  Use the old way of unpickling the instance
  911.                 # variables.  This is a semantic different when unpickling in
  912.                 # restricted vs. unrestricted modes.
  913.                 for k, v in value.items():
  914.                     setattr(inst, k, v)
  915.         else:
  916.             setstate(value)
  917.     dispatch[BUILD] = load_build
  918.  
  919.     def load_mark(self):
  920.         self.append(self.mark)
  921.     dispatch[MARK] = load_mark
  922.  
  923.     def load_stop(self):
  924.         value = self.stack[-1]
  925.         del self.stack[-1]
  926.         raise _Stop(value)
  927.     dispatch[STOP] = load_stop
  928.  
  929. # Helper class for load_inst/load_obj
  930.  
  931. class _EmptyClass:
  932.     pass
  933.  
  934. # Shorthands
  935.  
  936. from StringIO import StringIO
  937.  
  938. def dump(object, file, bin = 0):
  939.     Pickler(file, bin).dump(object)
  940.  
  941. def dumps(object, bin = 0):
  942.     file = StringIO()
  943.     Pickler(file, bin).dump(object)
  944.     return file.getvalue()
  945.  
  946. def load(file):
  947.     return Unpickler(file).load()
  948.  
  949. def loads(str):
  950.     file = StringIO(str)
  951.     return Unpickler(file).load()
  952.  
  953.  
  954. # The rest is used for testing only
  955.  
  956. class C:
  957.     def __cmp__(self, other):
  958.         return cmp(self.__dict__, other.__dict__)
  959.  
  960. def test():
  961.     fn = 'out'
  962.     c = C()
  963.     c.foo = 1
  964.     c.bar = 2
  965.     x = [0, 1, 2, 3]
  966.     y = ('abc', 'abc', c, c)
  967.     x.append(y)
  968.     x.append(y)
  969.     x.append(5)
  970.     f = open(fn, 'w')
  971.     F = Pickler(f)
  972.     F.dump(x)
  973.     f.close()
  974.     f = open(fn, 'r')
  975.     U = Unpickler(f)
  976.     x2 = U.load()
  977.     print x
  978.     print x2
  979.     print x == x2
  980.     print map(id, x)
  981.     print map(id, x2)
  982.     print F.memo
  983.     print U.memo
  984.  
  985. if __name__ == '__main__':
  986.     test()
  987.