[Python-checkins] python/dist/src/Lib pickle.py,1.72,1.73

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
Fri, 24 Jan 2003 11:29:55 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv30250

Modified Files:
	pickle.py 
Log Message:
Raise PicklingError when __reduce__() fails, and
add memoize() helper function to update the memo.

The first element of the tuple returned by __reduce__() must be a
callable.  If it isn't the Unpickler will raise an error.  Catch this
error in the pickler and raise the error there.

The memoize() helper also has a comment explaining how the memo
works.  So methods can't use memoize() because the write funny codes.


Index: pickle.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v
retrieving revision 1.72
retrieving revision 1.73
diff -C2 -d -r1.72 -r1.73
*** pickle.py	13 Nov 2002 22:01:26 -0000	1.72
--- pickle.py	24 Jan 2003 19:29:52 -0000	1.73
***************
*** 168,171 ****
--- 168,187 ----
          self.write(STOP)
  
+     def memoize(self, obj):
+         """Store an object in the memo."""
+ 
+         # The memo is a dictionary mapping object ids to 2-tuples
+         # that contains the memo value and the object being memoized.
+         # The memo value is written to the pickle and will become
+         # the key in the Unpickler's memo.  The object is stored in the
+         # memo so that transient objects are kept alive during pickling.
+ 
+         # The use of the memo length as the memo value is just a convention.
+         # The only requirement is that the memo values by unique.
+         d = id(obj)
+         memo_len = len(self.memo)
+         self.write(self.put(memo_len))
+         self.memo[d] = memo_len, obj
+ 
      def put(self, i):
          if self.bin:
***************
*** 281,289 ****
              self.write(BINPERSID)
  
!     def save_reduce(self, callable, arg_tup, state = None):
          write = self.write
          save = self.save
  
!         save(callable)
          save(arg_tup)
          write(REDUCE)
--- 297,309 ----
              self.write(BINPERSID)
  
!     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)
***************
*** 341,347 ****
  
      def save_string(self, object):
-         d = id(object)
-         memo = self.memo
- 
          if self.bin:
              l = len(object)
--- 361,364 ----
***************
*** 353,366 ****
          else:
              self.write(STRING + `object` + '\n')
! 
!         memo_len = len(memo)
!         self.write(self.put(memo_len))
!         memo[d] = (memo_len, object)
      dispatch[StringType] = save_string
  
      def save_unicode(self, object):
-         d = id(object)
-         memo = self.memo
- 
          if self.bin:
              encoding = object.encode('utf-8')
--- 370,377 ----
          else:
              self.write(STRING + `object` + '\n')
!         self.memoize(object)
      dispatch[StringType] = save_string
  
      def save_unicode(self, object):
          if self.bin:
              encoding = object.encode('utf-8')
***************
*** 372,379 ****
              object = object.replace("\n", "\\u000a")
              self.write(UNICODE + object.encode('raw-unicode-escape') + '\n')
! 
!         memo_len = len(memo)
!         self.write(self.put(memo_len))
!         memo[d] = (memo_len, object)
      dispatch[UnicodeType] = save_unicode
  
--- 383,387 ----
              object = object.replace("\n", "\\u000a")
              self.write(UNICODE + object.encode('raw-unicode-escape') + '\n')
!         self.memoize(object)
      dispatch[UnicodeType] = save_unicode
  
***************
*** 381,386 ****
          # This is true for Jython
          def save_string(self, object):
-             d = id(object)
-             memo = self.memo
              unicode = object.isunicode()
  
--- 389,392 ----
***************
*** 405,416 ****
                  else:
                      self.write(STRING + `object` + '\n')
! 
!             memo_len = len(memo)
!             self.write(self.put(memo_len))
!             memo[d] = (memo_len, object)
          dispatch[StringType] = save_string
  
      def save_tuple(self, object):
- 
          write = self.write
          save  = self.save
--- 411,418 ----
                  else:
                      self.write(STRING + `object` + '\n')
!             self.memoize(object)
          dispatch[StringType] = save_string
  
      def save_tuple(self, object):
          write = self.write
          save  = self.save
***************
*** 435,438 ****
--- 437,441 ----
          self.write(TUPLE + self.put(memo_len))
          memo[d] = (memo_len, object)
+ 
      dispatch[TupleType] = save_tuple
  
***************
*** 452,458 ****
              write(MARK + LIST)
  
!         memo_len = len(memo)
!         write(self.put(memo_len))
!         memo[d] = (memo_len, object)
  
          using_appends = (self.bin and (len(object) > 1))
--- 455,459 ----
              write(MARK + LIST)
  
!         self.memoize(object)
  
          using_appends = (self.bin and (len(object) > 1))
***************
*** 472,480 ****
  
      def save_dict(self, object):
-         d = id(object)
- 
          write = self.write
          save  = self.save
-         memo  = self.memo
  
          if self.bin:
--- 473,478 ----
***************
*** 483,489 ****
              write(MARK + DICT)
  
!         memo_len = len(memo)
!         self.write(self.put(memo_len))
!         memo[d] = (memo_len, object)
  
          using_setitems = (self.bin and (len(object) > 1))
--- 481,485 ----
              write(MARK + DICT)
  
!         self.memoize(object)
  
          using_setitems = (self.bin and (len(object) > 1))
***************
*** 530,533 ****
--- 526,531 ----
              save(arg)
  
+         # This method does not use memoize() so that it can handle
+         # the special case for non-binary mode.
          memo_len = len(memo)
          if self.bin: