Nick Coghlan added the comment:
Sorry for the long delay in doing anything with this patch. Unfortunately,
trunk has moved on quite a bit since this patch was submitted, and it's no
longer directly applicable.
However, the basic principle is sound, so this is a new patch that aligns with
the changes made in 3.4 to provide an iterator based bytecode introspection
API. It also changes the indenting to be based on the structure of the bytecode
disassembly - nested lines start aligned with the opcode *name* on the
preceding line. This will get unreadable with more than two or three levels of
nesting, but at that point, hard to read disassembly for the top level function
is the least of your worries. (A potentially useful option may to be add a flag
to turn off the implicit recursion, easily restoring the old single level
behaviour. I'd like the recursive version to be the default though, since it's
far more useful given that Python 3 comprehensions all involve a nested code
object)
A descriptive header makes the new output more self-explanatory. Note that I
did try repeating the code object repr from the LOAD_CONST opcode in the new
header - it was pretty unreadable, and redundant given the preceding line of
disassembly.
Two examples, one showing Torsten's list comprehension from above, and another
showing that the nested line numbers work properly.
This can't be applied as is - it's still missing tests, docs, and fixes to
disassembly output tests that assume the old behaviour.
>>> dis.dis('[x**2 for x in range(3)]')
1 0 LOAD_CONST 0 (<code object <listcomp> at
0x7f459ec4a0c0, file "<dis>", line 1>)
Disassembly for nested code object
1 0 BUILD_LIST 0
3 LOAD_FAST 0 (.0)
>> 6 FOR_ITER 16 (to 25)
9 STORE_FAST 1 (x)
12 LOAD_FAST 1 (x)
15 LOAD_CONST 0 (2)
18 BINARY_POWER
19 LIST_APPEND 2
22 JUMP_ABSOLUTE 6
>> 25 RETURN_VALUE
3 LOAD_CONST 1 ('<listcomp>')
6 MAKE_FUNCTION 0
9 LOAD_NAME 0 (range)
12 LOAD_CONST 2 (3)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
18 GET_ITER
19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
22 RETURN_VALUE
>>> def f():
... print("Hello")
... def g():
... for x in range(10):
... yield x
... return g
...
>>> dis.dis(f)
2 0 LOAD_GLOBAL 0 (print)
3 LOAD_CONST 1 ('Hello')
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
3 10 LOAD_CONST 2 (<code object g at 0x7f459ec4a540,
file "<stdin>", line 3>)
Disassembly for nested code object
4 0 SETUP_LOOP 25 (to 28)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (10)
9 CALL_FUNCTION 1 (1 positional, 0 keyword
pair)
12 GET_ITER
>> 13 FOR_ITER 11 (to 27)
16 STORE_FAST 0 (x)
5 19 LOAD_FAST 0 (x)
22 YIELD_VALUE
23 POP_TOP
24 JUMP_ABSOLUTE 13
>> 27 POP_BLOCK
>> 28 LOAD_CONST 0 (None)
31 RETURN_VALUE
13 LOAD_CONST 3 ('f.<locals>.g')
16 MAKE_FUNCTION 0
19 STORE_FAST 0 (g)
6 22 LOAD_FAST 0 (g)
25 RETURN_VALUE
----------
Added file: http://bugs.python.org/file36565/issue11822_nested_disassembly.diff
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue11822>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com