Commit d0f7c86a authored by Tim Peters's avatar Tim Peters

dis(): Not all opcodes are printable anymore, so print the repr

of the opcode character instead (but stripping the quotes).

Added a proto 2 test section for the canonical recursive-tuple case.
Note that since pickle's save_tuple() takes different paths depending on
tuple length now, beefier tests are really needed (but not in pickletools);
the "short tuple" case tried here was actually broken yesterday, and it's
subtle stuff so needs to be tested.
parent 1be31759
...@@ -1874,9 +1874,9 @@ def dis(pickle, out=None, indentlevel=4): ...@@ -1874,9 +1874,9 @@ def dis(pickle, out=None, indentlevel=4):
if pos is not None: if pos is not None:
print >> out, "%5d:" % pos, print >> out, "%5d:" % pos,
line = "%s %s%s" % (opcode.code, line = "%-4s %s%s" % (repr(opcode.code)[1:-1],
indentchunk * len(markstack), indentchunk * len(markstack),
opcode.name) opcode.name)
markmsg = None markmsg = None
if markstack and markobject in opcode.stack_before: if markstack and markobject in opcode.stack_before:
...@@ -1904,103 +1904,103 @@ _dis_test = """ ...@@ -1904,103 +1904,103 @@ _dis_test = """
>>> x = [1, 2, (3, 4), {'abc': u"def"}] >>> x = [1, 2, (3, 4), {'abc': u"def"}]
>>> pkl = pickle.dumps(x, 0) >>> pkl = pickle.dumps(x, 0)
>>> dis(pkl) >>> dis(pkl)
0: ( MARK 0: ( MARK
1: l LIST (MARK at 0) 1: l LIST (MARK at 0)
2: p PUT 0 2: p PUT 0
5: I INT 1 5: I INT 1
8: a APPEND 8: a APPEND
9: I INT 2 9: I INT 2
12: a APPEND 12: a APPEND
13: ( MARK 13: ( MARK
14: I INT 3 14: I INT 3
17: I INT 4 17: I INT 4
20: t TUPLE (MARK at 13) 20: t TUPLE (MARK at 13)
21: p PUT 1 21: p PUT 1
24: a APPEND 24: a APPEND
25: ( MARK 25: ( MARK
26: d DICT (MARK at 25) 26: d DICT (MARK at 25)
27: p PUT 2 27: p PUT 2
30: S STRING 'abc' 30: S STRING 'abc'
37: p PUT 3 37: p PUT 3
40: V UNICODE u'def' 40: V UNICODE u'def'
45: p PUT 4 45: p PUT 4
48: s SETITEM 48: s SETITEM
49: a APPEND 49: a APPEND
50: . STOP 50: . STOP
Try again with a "binary" pickle. Try again with a "binary" pickle.
>>> pkl = pickle.dumps(x, 1) >>> pkl = pickle.dumps(x, 1)
>>> dis(pkl) >>> dis(pkl)
0: ] EMPTY_LIST 0: ] EMPTY_LIST
1: q BINPUT 0 1: q BINPUT 0
3: ( MARK 3: ( MARK
4: K BININT1 1 4: K BININT1 1
6: K BININT1 2 6: K BININT1 2
8: ( MARK 8: ( MARK
9: K BININT1 3 9: K BININT1 3
11: K BININT1 4 11: K BININT1 4
13: t TUPLE (MARK at 8) 13: t TUPLE (MARK at 8)
14: q BINPUT 1 14: q BINPUT 1
16: } EMPTY_DICT 16: } EMPTY_DICT
17: q BINPUT 2 17: q BINPUT 2
19: U SHORT_BINSTRING 'abc' 19: U SHORT_BINSTRING 'abc'
24: q BINPUT 3 24: q BINPUT 3
26: X BINUNICODE u'def' 26: X BINUNICODE u'def'
34: q BINPUT 4 34: q BINPUT 4
36: s SETITEM 36: s SETITEM
37: e APPENDS (MARK at 3) 37: e APPENDS (MARK at 3)
38: . STOP 38: . STOP
Exercise the INST/OBJ/BUILD family. Exercise the INST/OBJ/BUILD family.
>>> import random >>> import random
>>> dis(pickle.dumps(random.random, 0)) >>> dis(pickle.dumps(random.random, 0))
0: c GLOBAL 'random random' 0: c GLOBAL 'random random'
15: p PUT 0 15: p PUT 0
18: . STOP 18: . STOP
>>> x = [pickle.PicklingError()] * 2 >>> x = [pickle.PicklingError()] * 2
>>> dis(pickle.dumps(x, 0)) >>> dis(pickle.dumps(x, 0))
0: ( MARK 0: ( MARK
1: l LIST (MARK at 0) 1: l LIST (MARK at 0)
2: p PUT 0 2: p PUT 0
5: ( MARK 5: ( MARK
6: i INST 'pickle PicklingError' (MARK at 5) 6: i INST 'pickle PicklingError' (MARK at 5)
28: p PUT 1 28: p PUT 1
31: ( MARK 31: ( MARK
32: d DICT (MARK at 31) 32: d DICT (MARK at 31)
33: p PUT 2 33: p PUT 2
36: S STRING 'args' 36: S STRING 'args'
44: p PUT 3 44: p PUT 3
47: ( MARK 47: ( MARK
48: t TUPLE (MARK at 47) 48: t TUPLE (MARK at 47)
49: s SETITEM 49: s SETITEM
50: b BUILD 50: b BUILD
51: a APPEND 51: a APPEND
52: g GET 1 52: g GET 1
55: a APPEND 55: a APPEND
56: . STOP 56: . STOP
>>> dis(pickle.dumps(x, 1)) >>> dis(pickle.dumps(x, 1))
0: ] EMPTY_LIST 0: ] EMPTY_LIST
1: q BINPUT 0 1: q BINPUT 0
3: ( MARK 3: ( MARK
4: ( MARK 4: ( MARK
5: c GLOBAL 'pickle PicklingError' 5: c GLOBAL 'pickle PicklingError'
27: q BINPUT 1 27: q BINPUT 1
29: o OBJ (MARK at 4) 29: o OBJ (MARK at 4)
30: q BINPUT 2 30: q BINPUT 2
32: } EMPTY_DICT 32: } EMPTY_DICT
33: q BINPUT 3 33: q BINPUT 3
35: U SHORT_BINSTRING 'args' 35: U SHORT_BINSTRING 'args'
41: q BINPUT 4 41: q BINPUT 4
43: ) EMPTY_TUPLE 43: ) EMPTY_TUPLE
44: s SETITEM 44: s SETITEM
45: b BUILD 45: b BUILD
46: h BINGET 2 46: h BINGET 2
48: e APPENDS (MARK at 3) 48: e APPENDS (MARK at 3)
49: . STOP 49: . STOP
Try "the canonical" recursive-object test. Try "the canonical" recursive-object test.
...@@ -2016,24 +2016,24 @@ True ...@@ -2016,24 +2016,24 @@ True
>>> T[0][0] is T >>> T[0][0] is T
True True
>>> dis(pickle.dumps(L, 0)) >>> dis(pickle.dumps(L, 0))
0: ( MARK 0: ( MARK
1: l LIST (MARK at 0) 1: l LIST (MARK at 0)
2: p PUT 0 2: p PUT 0
5: ( MARK 5: ( MARK
6: g GET 0 6: g GET 0
9: t TUPLE (MARK at 5) 9: t TUPLE (MARK at 5)
10: p PUT 1 10: p PUT 1
13: a APPEND 13: a APPEND
14: . STOP 14: . STOP
>>> dis(pickle.dumps(L, 1)) >>> dis(pickle.dumps(L, 1))
0: ] EMPTY_LIST 0: ] EMPTY_LIST
1: q BINPUT 0 1: q BINPUT 0
3: ( MARK 3: ( MARK
4: h BINGET 0 4: h BINGET 0
6: t TUPLE (MARK at 3) 6: t TUPLE (MARK at 3)
7: q BINPUT 1 7: q BINPUT 1
9: a APPEND 9: a APPEND
10: . STOP 10: . STOP
The protocol 0 pickle of the tuple causes the disassembly to get confused, The protocol 0 pickle of the tuple causes the disassembly to get confused,
as it doesn't realize that the POP opcode at 16 gets rid of the MARK at 0 as it doesn't realize that the POP opcode at 16 gets rid of the MARK at 0
...@@ -2043,31 +2043,55 @@ POP_MARK gets rid of the MARK. Doing a better job on the protocol 0 ...@@ -2043,31 +2043,55 @@ POP_MARK gets rid of the MARK. Doing a better job on the protocol 0
pickle would require the disassembler to emulate the stack. pickle would require the disassembler to emulate the stack.
>>> dis(pickle.dumps(T, 0)) >>> dis(pickle.dumps(T, 0))
0: ( MARK 0: ( MARK
1: ( MARK 1: ( MARK
2: l LIST (MARK at 1) 2: l LIST (MARK at 1)
3: p PUT 0 3: p PUT 0
6: ( MARK 6: ( MARK
7: g GET 0 7: g GET 0
10: t TUPLE (MARK at 6) 10: t TUPLE (MARK at 6)
11: p PUT 1 11: p PUT 1
14: a APPEND 14: a APPEND
15: 0 POP 15: 0 POP
16: 0 POP 16: 0 POP
17: g GET 1 17: g GET 1
20: . STOP 20: . STOP
>>> dis(pickle.dumps(T, 1)) >>> dis(pickle.dumps(T, 1))
0: ( MARK 0: ( MARK
1: ] EMPTY_LIST 1: ] EMPTY_LIST
2: q BINPUT 0 2: q BINPUT 0
4: ( MARK 4: ( MARK
5: h BINGET 0 5: h BINGET 0
7: t TUPLE (MARK at 4) 7: t TUPLE (MARK at 4)
8: q BINPUT 1 8: q BINPUT 1
10: a APPEND 10: a APPEND
11: 1 POP_MARK (MARK at 0) 11: 1 POP_MARK (MARK at 0)
12: h BINGET 1 12: h BINGET 1
14: . STOP 14: . STOP
Try protocol 2.
>>> dis(pickle.dumps(L, 2))
0: \x80 PROTO 2
2: ] EMPTY_LIST
3: q BINPUT 0
5: h BINGET 0
7: \x85 TUPLE1
8: q BINPUT 1
10: a APPEND
11: . STOP
>>> dis(pickle.dumps(T, 2))
0: \x80 PROTO 2
2: ] EMPTY_LIST
3: q BINPUT 0
5: h BINGET 0
7: \x85 TUPLE1
8: q BINPUT 1
10: a APPEND
11: 0 POP
12: h BINGET 1
14: . STOP
""" """
__test__ = {'disassembler_test': _dis_test, __test__ = {'disassembler_test': _dis_test,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment