New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance dis.dis to autocompile codestrings #50756
Comments
dis.dis(ob) currently accepts "a module, a class, a method, a function, On the Python ideas list, Steven D'Aprano raised the issue of 'exec' >>> dis(compile('x = x+1', '', 'single'))
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (1)
6 BINARY_ADD
7 STORE_NAME 0 (x)
10 LOAD_CONST 1 (None)
13 RETURN_VALUE
>>> dis(compile('x = x+1', '', 'exec'))
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (1)
6 BINARY_ADD
7 STORE_NAME 0 (x)
10 LOAD_CONST 1 (None)
13 RETURN_VALUE Using 'exec' instead of 'eval' adds two spurious, but easily ignored, lines. >>> dis(compile('x+1','', 'eval'))
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (1)
6 BINARY_ADD
7 RETURN_VALUE
>>> dis(compile('x+1', '', 'exec'))
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (1)
6 BINARY_ADD
7 POP_TOP
8 LOAD_CONST 1 (None)
11 RETURN_VALUE Between the current doc sentences "For a single code sequence, it prints "Strings are first compiled as statements to code objects with 'compile' should be cross-referenced to its listing under built-in |
Copying my suggestion (minus examples) over from the python-ideas thread: We could define it as trying the three modes in order (first 'eval', from dis import dis
def dis_str(source):
modes = ('eval', 'single', 'exec')
for mode in modes:
try:
c = compile(source, '', mode)
break
except SyntaxError:
if mode is modes[-1]:
raise
return dis(c) |
As I explained on python-ideas, 'single' should not be tried. |
As per Georg's suggestion, a better approach would look like: from dis import dis
def dis_str(source):
try:
c = compile(source, '', 'eval')
except SyntaxError:
c = compile(source, '', 'exec')
return dis(c) |
Trying both 'eval' and 'exec' looks fine to me. |
I've made a patch, which adds a disassemble_str function to the dis module. The dis.dis function calls this function if x is a string. Added the following sentence to the documentation: "Strings are first compiled to code objects with the :func:`compile` built-in function." Added two simle unittests. |
+1 |
Any chance, that my patch will be accepted? Is there a problem with it? Thanks. |
disassemble_str should be private with an underscore. |
Done. Attached new patch as issue6507_2_priv.diff. |
Missed the window for 2.7, but should be right for 3.2. There's a minor error in the documentation (strings need to be mentioned in the list of acceptable types), but I can fix that on commit. |
disassemble_string should've been private as well, while we are editing this module. |
Attached the updated patch. |
Just today, someone posted the result of dis.dis('somebytes') and did not notice the error because dis blithely disassembles bytes as bytecodes, even in 3.x. (The person actually dissed a 2.x string). >>> from dis import dis
>>> dis(b'cat')
0 DUP_TOPX 29793 It is a natural thing to do, so I hope this is put in 3.2. Since the undocumented 'disassemble_string' now disassembles bytes, I think it should be renamed '_disassemble_bytes' instead of '_disassemble_string'. This would accord with the general effort to remove 2.x fossils from 3.x. Aside from that, it looks ready, from a reading review, to apply and test: doc addition, added tests, new function and else case, and rename. |
Committed (with some minor modifications) in r82471. Inspired by Yanov Aknin's ssc() tool, I've opened a new RFE (bpo-9147) for a similarly enhanced show_code() implementation. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: