save_tuple(): Minor rewriting, and added a comment about the subtlety
authorTim Peters <tim.peters@gmail.com>
Tue, 28 Jan 2003 02:09:55 +0000 (02:09 +0000)
committerTim Peters <tim.peters@gmail.com>
Tue, 28 Jan 2003 02:09:55 +0000 (02:09 +0000)
created by recursive tuples.

Lib/pickle.py

index 62f7a5849a725614a90c8e73888e8bd276f4336e..25a5a55626e2acaaedbec9e14bef243d69c0c695 100644 (file)
@@ -454,21 +454,26 @@ class Pickler:
         save  = self.save
         memo  = self.memo
 
-        d = id(object)
-
         write(MARK)
-
         for element in object:
             save(element)
 
-        if len(object) and d in memo:
+        if object and id(object) in memo:
+            # Subtle.  d was not in memo when we entered save_tuple(), so
+            # the process of saving the tuple's elements must have saved
+            # the tuple itself:  the tuple is recursive.  The proper action
+            # now is to throw away everything we put on the stack, and
+            # simply GET the tuple (it's already constructed).  This check
+            # could have been done in the "for element" loop instead, but
+            # recursive tuples are a rare thing.
+            get = self.get(memo[id(object)][0])
             if self.bin:
-                write(POP_MARK + self.get(memo[d][0]))
-                return
-
-            write(POP * (len(object) + 1) + self.get(memo[d][0]))
+                write(POP_MARK + get)
+            else:   # proto 0 -- POP_MARK not available
+                write(POP * (len(object) + 1) + get)
             return
 
+        # No recursion (including the empty-tuple case).
         self.write(TUPLE)
         self.memoize(object)