summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-01-30 06:37:41 (GMT)
committerGuido van Rossum <guido@python.org>2003-01-30 06:37:41 (GMT)
commit9b40e804c79cef8dd240b734589e7caffd8ee4bd (patch)
treed3ca0eee59e25084d0619474170643a19d164c1a
parent4fba220f4ad9203894ef95512f8c9cc5593c5567 (diff)
downloadcpython-9b40e804c79cef8dd240b734589e7caffd8ee4bd.zip
cpython-9b40e804c79cef8dd240b734589e7caffd8ee4bd.tar.gz
cpython-9b40e804c79cef8dd240b734589e7caffd8ee4bd.tar.bz2
There was a subtle big in save_newobj(): it used self.save_global(t)
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. :-(
-rw-r--r--Lib/pickle.py3
1 files changed, 2 insertions, 1 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index 9bd2394..4c4bf86 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -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)