]> granicus.if.org Git - python/commitdiff
There was a subtle big in save_newobj(): it used self.save_global(t)
authorGuido van Rossum <guido@python.org>
Thu, 30 Jan 2003 06:37:41 +0000 (06:37 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 30 Jan 2003 06:37:41 +0000 (06:37 +0000)
on the type instead of self.save(t).  This defeated the purpose of
NEWOBJ, because it didn't generate a BINGET opcode when t was already
memoized; but moreover, it would generate multiple BINPUT opcodes for
the same type!  pickletools.dis() doesn't like this.

How I found this?  I was playing with picklesize.py in the datetime
sandbox, and noticed that protocol 2 pickles for multiple objects were
in fact larger than protocol 1 pickles!  That was suspicious, so I
decided to disassemble one of the pickles.

This really needs a unit test, but I'm exhausted.  I'll be late for
work as it is. :-(

Lib/pickle.py

index 9bd2394d66c29a92f0f6219b3aec49e5a086f74e..4c4bf861c42b6d93db19f038d69bafd4ec307321 100644 (file)
@@ -233,6 +233,7 @@ class Pickler:
         # growable) array, indexed by memo key.
         if self.fast:
             return
+        assert id(obj) not in self.memo
         memo_len = len(self.memo)
         self.write(self.put(memo_len))
         self.memo[id(obj)] = memo_len, obj
@@ -386,7 +387,7 @@ class Pickler:
         save = self.save
         write = self.write
 
-        self.save_global(t)
+        self.save(t)
         save(args)
         write(NEWOBJ)
         self.memoize(obj)