[Python-checkins] python/dist/src/Lib pickle.py,1.109,1.110
gvanrossum@users.sourceforge.net
gvanrossum@users.sourceforge.net
Tue, 28 Jan 2003 08:34:25 -0800
Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv24598
Modified Files:
pickle.py
Log Message:
Made save() fit on a page, while adding comments. (I moved some type
checks to save_reduce(), which can also be called from a subclass.)
Also tweaked some more comments.
Index: pickle.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v
retrieving revision 1.109
retrieving revision 1.110
diff -C2 -d -r1.109 -r1.110
*** pickle.py 28 Jan 2003 16:23:33 -0000 1.109
--- pickle.py 28 Jan 2003 16:34:19 -0000 1.110
***************
*** 33,36 ****
--- 33,37 ----
import struct
import re
+ import warnings
__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
***************
*** 40,44 ****
format_version = "2.0" # File format version we write
compatible_formats = ["1.0", # Original protocol 0
! "1.1", # Protocol 0 with class supprt added
"1.2", # Original protocol 1
"1.3", # Protocol 1 with BINFLOAT added
--- 41,45 ----
format_version = "2.0" # File format version we write
compatible_formats = ["1.0", # Original protocol 0
! "1.1", # Protocol 0 with INST added
"1.2", # Original protocol 1
"1.3", # Protocol 1 with BINFLOAT added
***************
*** 250,277 ****
def save(self, obj):
pid = self.persistent_id(obj)
! if pid is not None:
self.save_pers(pid)
return
! memo = self.memo
! d = id(obj)
! if d in memo:
! self.write(self.get(memo[d][0]))
return
t = type(obj)
! try:
! f = self.dispatch[t]
! except KeyError:
! pass
! else:
! f(self, obj)
return
! # The dispatch table doesn't know about type t.
try:
issc = issubclass(t, TypeType)
! except TypeError: # t is not a class
issc = 0
if issc:
--- 251,277 ----
def save(self, obj):
+ # Check for persistent id (defined by a subclass)
pid = self.persistent_id(obj)
! if pid:
self.save_pers(pid)
return
! # Check the memo
! x = self.memo.get(id(obj))
! if x:
! self.write(self.get(x[0]))
return
+ # Check the type dispatch table
t = type(obj)
! f = self.dispatch.get(t)
! if f:
! f(self, obj) # Call unbound method with explicit self
return
! # Check for a class with a custom metaclass; treat as regular class
try:
issc = issubclass(t, TypeType)
! except TypeError: # t is not a class (old Boost; see SF #502085)
issc = 0
if issc:
***************
*** 279,329 ****
return
! try:
! reduce = dispatch_table[t]
! except KeyError:
! try:
! reduce = obj.__reduce__
! except AttributeError:
! raise PicklingError, \
! "can't pickle %s object: %s" % (`t.__name__`,
! `obj`)
! else:
! tup = reduce()
else:
! tup = reduce(obj)
! if type(tup) is StringType:
! self.save_global(obj, tup)
return
! if type(tup) is not TupleType:
! raise PicklingError, "Value returned by %s must be a " \
! "tuple" % reduce
!
! l = len(tup)
!
! if (l != 2) and (l != 3):
! raise PicklingError, "tuple returned by %s must contain " \
! "only two or three elements" % reduce
!
! callable = tup[0]
! arg_tup = tup[1]
! if l > 2:
! state = tup[2]
! else:
state = None
! if type(arg_tup) is not TupleType and arg_tup is not None:
! raise PicklingError, "Second element of tuple returned " \
! "by %s must be a tuple" % reduce
!
! self.save_reduce(callable, arg_tup, state)
self.memoize(obj)
def persistent_id(self, obj):
return None
def save_pers(self, pid):
if self.bin:
self.save(pid)
--- 279,324 ----
return
! # Check copy_reg.dispatch_table
! reduce = dispatch_table.get(t)
! if reduce:
! rv = reduce(obj)
else:
! # Check for __reduce__ method
! reduce = getattr(obj, "__reduce__", None)
! if not reduce:
! raise PicklingError("Can't pickle %r object: %r" %
! (t.__name__, obj))
! rv = reduce()
! # Check for string returned by reduce(), meaning "save as global"
! if type(rv) is StringType:
! self.save_global(obj, rv)
return
! # Assert that reduce() returned a tuple
! if type(rv) is not TupleType:
! raise PicklingError("%s must return string or tuple" % reduce)
! # Assert that it returned a 2-tuple or 3-tuple, and unpack it
! l = len(rv)
! if l == 2:
! func, args = rv
state = None
+ elif l == 3:
+ func, args, state = rv
+ else:
+ raise PicklingError("Tuple returned by %s must have "
+ "exactly two or three elements" % reduce)
! # Save the reduce() output and finally memoize the object
! self.save_reduce(func, args, state)
self.memoize(obj)
def persistent_id(self, obj):
+ # This exists so a subclass can override it
return None
def save_pers(self, pid):
+ # Save a persistent id reference
if self.bin:
self.save(pid)
***************
*** 332,345 ****
self.write(PERSID + str(pid) + '\n')
! def save_reduce(self, acallable, arg_tup, state = None):
! write = self.write
! save = self.save
! if not callable(acallable):
! raise PicklingError("__reduce__() must return callable as "
! "first argument, not %s" % `acallable`)
! save(acallable)
! save(arg_tup)
write(REDUCE)
--- 327,353 ----
self.write(PERSID + str(pid) + '\n')
! def save_reduce(self, func, args, state=None):
! # This API is be called by some subclasses
! # Assert that args is a tuple or None
! if not isinstance(args, TupleType):
! if args is None:
! # A hack for Jim Fulton's ExtensionClass, now deprecated.
! # See load_reduce()
! warnings.warn("__basicnew__ special case is deprecated",
! DeprecationWarning)
! else:
! raise PicklingError(
! "args from reduce() should be a tuple")
! # Assert that func is callable
! if not callable(func):
! raise PicklingError("func from reduce should be callable")
!
! save = self.save
! write = self.write
!
! save(func)
! save(args)
write(REDUCE)
***************
*** 348,351 ****
--- 356,361 ----
write(BUILD)
+ # Methods below this point are dispatched through the dispatch table
+
dispatch = {}
***************
*** 1029,1035 ****
if arg_tup is None:
! import warnings
! warnings.warn("The None return argument form of __reduce__ is "
! "deprecated. Return a tuple of arguments instead.",
DeprecationWarning)
value = callable.__basicnew__()
--- 1039,1044 ----
if arg_tup is None:
! # A hack for Jim Fulton's ExtensionClass, now deprecated
! warnings.warn("__basicnew__ special case is deprecated",
DeprecationWarning)
value = callable.__basicnew__()