summaryrefslogtreecommitdiffstats
path: root/Lib/pickletools.py
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2003-02-05 19:55:53 (GMT)
committerTim Peters <tim.peters@gmail.com>2003-02-05 19:55:53 (GMT)
commit62235e701e377fd1e4934bc029b9b86d8dc3ed95 (patch)
tree74c470a48151126f240156a34cfea5a8bb8d9186 /Lib/pickletools.py
parent18e7083cda52fec41ee5583bd04a916d4a6330f7 (diff)
downloadcpython-62235e701e377fd1e4934bc029b9b86d8dc3ed95.zip
cpython-62235e701e377fd1e4934bc029b9b86d8dc3ed95.tar.gz
cpython-62235e701e377fd1e4934bc029b9b86d8dc3ed95.tar.bz2
dis(): Added an optional memo argument, so that multiple pickles in a
file can be dumped without (bogus) complaint if the the pickles were created using a single pickle memo.
Diffstat (limited to 'Lib/pickletools.py')
-rw-r--r--Lib/pickletools.py40
1 files changed, 38 insertions, 2 deletions
diff --git a/Lib/pickletools.py b/Lib/pickletools.py
index f9ef8df..195f5c6 100644
--- a/Lib/pickletools.py
+++ b/Lib/pickletools.py
@@ -1861,7 +1861,7 @@ def genops(pickle):
##############################################################################
# A symbolic pickle disassembler.
-def dis(pickle, out=None, indentlevel=4):
+def dis(pickle, out=None, memo=None, indentlevel=4):
"""Produce a symbolic disassembly of a pickle.
'pickle' is a file-like object, or string, containing a (at least one)
@@ -1871,6 +1871,12 @@ def dis(pickle, out=None, indentlevel=4):
Optional arg 'out' is a file-like object to which the disassembly is
printed. It defaults to sys.stdout.
+ Optional arg 'memo' is a Python dict, used as the pickle's memo. It
+ may be mutated by dis(), if the pickle contains PUT or BINPUT opcodes.
+ Passing the same memo object to another dis() call then allows disassembly
+ to proceed across multiple pickles that were all created by the same
+ pickler with the same memo. Ordinarily you don't need to worry about this.
+
Optional arg indentlevel is the number of blanks by which to indent
a new MARK level. It defaults to 4.
@@ -1895,7 +1901,8 @@ def dis(pickle, out=None, indentlevel=4):
# (which in turn is needed to indent MARK blocks correctly).
stack = [] # crude emulation of unpickler stack
- memo = {} # crude emulation of unpicker memo
+ if memo is None:
+ memo = {} # crude emulation of unpicker memo
maxproto = -1 # max protocol number seen
markstack = [] # bytecode positions of MARK opcodes
indentchunk = ' ' * indentlevel
@@ -2195,7 +2202,36 @@ highest protocol among opcodes = 2
highest protocol among opcodes = 2
"""
+_memo_test = r"""
+>>> import pickle
+>>> from StringIO import StringIO
+>>> f = StringIO()
+>>> p = pickle.Pickler(f, 2)
+>>> x = [1, 2, 3]
+>>> p.dump(x)
+>>> p.dump(x)
+>>> f.seek(0)
+>>> memo = {}
+>>> dis(f, memo=memo)
+ 0: \x80 PROTO 2
+ 2: ] EMPTY_LIST
+ 3: q BINPUT 0
+ 5: ( MARK
+ 6: K BININT1 1
+ 8: K BININT1 2
+ 10: K BININT1 3
+ 12: e APPENDS (MARK at 5)
+ 13: . STOP
+highest protocol among opcodes = 2
+>>> dis(f, memo=memo)
+ 14: \x80 PROTO 2
+ 16: h BINGET 0
+ 18: . STOP
+highest protocol among opcodes = 2
+"""
+
__test__ = {'disassembler_test': _dis_test,
+ 'disassembler_memo_test': _memo_test,
}
def _test():