You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Merge branch 'master' into python-2.4
This commit is contained in:
7
NEWS
7
NEWS
@@ -1,3 +1,10 @@
|
|||||||
|
uncompyle6 3.2.0 2018-05-19 Rocket Scientist
|
||||||
|
|
||||||
|
- Add rudimentary 1.4 support (still a bit buggy)
|
||||||
|
- add --tree+ option to show formatting rule, when it is constant
|
||||||
|
- Python 2.7.15candidate1 support (via xdis)
|
||||||
|
- bug fixes, especially for 3.7 (but 2.7 and 3.6 and others as well)
|
||||||
|
|
||||||
uncompyle6 3.1.3 2018-04-16
|
uncompyle6 3.1.3 2018-04-16
|
||||||
|
|
||||||
- Add some Python 3.7 rules, such as for handling LOAD_METHOD (not complete)
|
- Add some Python 3.7 rules, such as for handling LOAD_METHOD (not complete)
|
||||||
|
@@ -56,7 +56,7 @@ entry_points = {
|
|||||||
]}
|
]}
|
||||||
ftp_url = None
|
ftp_url = None
|
||||||
install_requires = ['spark-parser >= 1.8.5, < 1.9.0',
|
install_requires = ['spark-parser >= 1.8.5, < 1.9.0',
|
||||||
'xdis >= 3.7.0, < 3.8.0']
|
'xdis >= 3.8.2, < 3.9.0']
|
||||||
license = 'GPL3'
|
license = 'GPL3'
|
||||||
mailing_list = 'python-debugger@googlegroups.com'
|
mailing_list = 'python-debugger@googlegroups.com'
|
||||||
modname = 'uncompyle6'
|
modname = 'uncompyle6'
|
||||||
|
@@ -6,6 +6,7 @@ machine:
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
override:
|
override:
|
||||||
|
- pip install --upgrade setuptools
|
||||||
- pip install -e .
|
- pip install -e .
|
||||||
- pip install pytest==3.2.5 hypothesis
|
- pip install pytest==3.2.5 hypothesis
|
||||||
test:
|
test:
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
|
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
|
||||||
check-bytecode-1.5 check-bytecode-1 check-bytecode-2 check-bytecode-3 \
|
check-bytecode-1 check-bytecode-1.4 check-bytecode-1.5 \
|
||||||
|
check-bytecode-2 check-bytecode-3 \
|
||||||
check-bytecode-2.2 check-byteocde-2.3 check-bytecode-2.4 \
|
check-bytecode-2.2 check-byteocde-2.3 check-bytecode-2.4 \
|
||||||
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
|
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
|
||||||
check-3.4 check-3.5 check-3.6 check-3.7 check-5.6 5.6 5.8 \
|
check-3.4 check-3.5 check-3.6 check-3.7 check-5.6 5.6 5.8 \
|
||||||
@@ -76,7 +77,7 @@ check-disasm:
|
|||||||
$(PYTHON) dis-compare.py
|
$(PYTHON) dis-compare.py
|
||||||
|
|
||||||
#: Check deparsing bytecode 1.x only
|
#: Check deparsing bytecode 1.x only
|
||||||
check-bytecode-1: check-bytecode-1.5
|
check-bytecode-1: check-bytecode-1.4 check-bytecode-1.5
|
||||||
|
|
||||||
#: Check deparsing bytecode 2.x only
|
#: Check deparsing bytecode 2.x only
|
||||||
check-bytecode-2:
|
check-bytecode-2:
|
||||||
@@ -93,11 +94,17 @@ check-bytecode-3:
|
|||||||
#: Check deparsing bytecode that works running Python 2 and Python 3
|
#: Check deparsing bytecode that works running Python 2 and Python 3
|
||||||
check-bytecode: check-bytecode-3
|
check-bytecode: check-bytecode-3
|
||||||
$(PYTHON) test_pythonlib.py \
|
$(PYTHON) test_pythonlib.py \
|
||||||
|
--bytecode-1.4 --bytecode-1.5 \
|
||||||
|
--bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
||||||
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
|
||||||
--bytecode-2.5 --bytecode-2.6 --bytecode-2.7 \
|
--bytecode-2.5 --bytecode-2.6 --bytecode-2.7 \
|
||||||
--bytecode-pypy2.7
|
--bytecode-pypy2.7
|
||||||
|
|
||||||
|
|
||||||
|
#: Check deparsing bytecode 1.4 only
|
||||||
|
check-bytecode-1.4:
|
||||||
|
$(PYTHON) test_pythonlib.py --bytecode-1.4
|
||||||
|
|
||||||
#: Check deparsing bytecode 1.5 only
|
#: Check deparsing bytecode 1.5 only
|
||||||
check-bytecode-1.5:
|
check-bytecode-1.5:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-1.5
|
$(PYTHON) test_pythonlib.py --bytecode-1.5
|
||||||
|
BIN
test/bytecode_1.4/emacs.pyc
Normal file
BIN
test/bytecode_1.4/emacs.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_class-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_class-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_del-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_del-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_docstring-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_docstring-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_empty-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_empty-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_global-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_global-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_globals-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_globals-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_single_stmt-1.4.pyc
Normal file
BIN
test/bytecode_1.4/test_single_stmt-1.4.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.6_run/03_complex_and.pyc
Normal file
BIN
test/bytecode_2.6_run/03_complex_and.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7/05_try_else.pyc-notyet
Normal file
BIN
test/bytecode_2.7/05_try_else.pyc-notyet
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.1_run/05_dict_comp.pyc
Normal file
BIN
test/bytecode_3.1_run/05_dict_comp.pyc
Normal file
Binary file not shown.
Binary file not shown.
17
test/simple_source/bug26/03_complex_and.py
Normal file
17
test/simple_source/bug26/03_complex_and.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# From 2.6 test_datetime.py
|
||||||
|
# Bug is in parsing (x is 0 or x is 1) and (y is 5 or y is 2)
|
||||||
|
# correctly.
|
||||||
|
|
||||||
|
# This code is RUNNABLE!
|
||||||
|
result = []
|
||||||
|
for y in (1, 2, 10):
|
||||||
|
x = cmp(1, y)
|
||||||
|
if (x is 0 or x is 1) and (y is 5 or y is 2):
|
||||||
|
expected = 10
|
||||||
|
elif y is 2:
|
||||||
|
expected = 2
|
||||||
|
else:
|
||||||
|
expected = 3
|
||||||
|
result.append(expected)
|
||||||
|
|
||||||
|
assert result == [10, 2, 3]
|
11
test/simple_source/bug27+/05_try_else.py
Normal file
11
test/simple_source/bug27+/05_try_else.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# From Python 2.7 test_ziplib.py
|
||||||
|
# Bug is distinguishing try from try/else.
|
||||||
|
def testAFakeZlib(self):
|
||||||
|
try:
|
||||||
|
self.doTest()
|
||||||
|
except ImportError:
|
||||||
|
if self.compression != 3:
|
||||||
|
self.fail("expected test to not raise ImportError")
|
||||||
|
else:
|
||||||
|
if self.compression != 4:
|
||||||
|
self.fail("expected test to raise ImportError")
|
@@ -1,4 +1,7 @@
|
|||||||
|
# Bug was in dictionary comprehension involving "if not"
|
||||||
# Issue #162
|
# Issue #162
|
||||||
|
#
|
||||||
|
# This code is RUNNABLE!
|
||||||
def x(s):
|
def x(s):
|
||||||
return {k: v
|
return {k: v
|
||||||
for (k, v) in s
|
for (k, v) in s
|
||||||
|
@@ -75,12 +75,24 @@ case $PYVERSION in
|
|||||||
# .pyenv/versions/2.6.9/lib/python2.6/sre_parse.pyc
|
# .pyenv/versions/2.6.9/lib/python2.6/sre_parse.pyc
|
||||||
# .pyenv/versions/2.6.9/lib/python2.6/tabnanny.pyc
|
# .pyenv/versions/2.6.9/lib/python2.6/tabnanny.pyc
|
||||||
# .pyenv/versions/2.6.9/lib/python2.6/tarfile.pyc
|
# .pyenv/versions/2.6.9/lib/python2.6/tarfile.pyc
|
||||||
|
|
||||||
|
# Not getting set by bach below?
|
||||||
|
[test_pprint.py]=1
|
||||||
|
|
||||||
)
|
)
|
||||||
if (( batch )) ; then
|
if (( batch )) ; then
|
||||||
# Fails in crontab environment?
|
# Fails in crontab environment?
|
||||||
# Figure out what's up here
|
# Figure out what's up here
|
||||||
SKIP_TESTS[test_aifc.py]=1
|
SKIP_TESTS[test_aifc.py]=1
|
||||||
SKIP_TESTS[test_array.py]=1
|
SKIP_TESTS[test_array.py]=1
|
||||||
|
|
||||||
|
# SyntaxError: Non-ASCII character '\xdd' in file test_base64.py on line 153, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
|
||||||
|
SKIP_TESTS[test_base64.py]=1
|
||||||
|
|
||||||
|
# output indicates expected == output, but this fails anyway.
|
||||||
|
# Maybe the underlying encoding is subtlely different so it
|
||||||
|
# looks the same?
|
||||||
|
SKIP_TESTS[test_pprint.py]=1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
2.7)
|
2.7)
|
||||||
@@ -111,6 +123,7 @@ case $PYVERSION in
|
|||||||
[test_unicode.py]=1 # Too long to run 11 seconds
|
[test_unicode.py]=1 # Too long to run 11 seconds
|
||||||
[test_xpickle.py]=1 # Runs ok but takes 72 seconds
|
[test_xpickle.py]=1 # Runs ok but takes 72 seconds
|
||||||
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
|
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
|
||||||
|
[test_zipimport.py]=1 # We can't distinguish try from try/else yet
|
||||||
)
|
)
|
||||||
if (( batch )) ; then
|
if (( batch )) ; then
|
||||||
# Fails in crontab environment?
|
# Fails in crontab environment?
|
||||||
@@ -118,6 +131,9 @@ case $PYVERSION in
|
|||||||
SKIP_TESTS[test_array.py]=1
|
SKIP_TESTS[test_array.py]=1
|
||||||
SKIP_TESTS[test_ast.py]=1
|
SKIP_TESTS[test_ast.py]=1
|
||||||
SKIP_TESTS[test_audioop.py]=1
|
SKIP_TESTS[test_audioop.py]=1
|
||||||
|
|
||||||
|
# SyntaxError: Non-ASCII character '\xdd' in file test_base64.py on line 153, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
|
||||||
|
SKIP_TESTS[test_base64.py]=1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
3.5)
|
3.5)
|
||||||
|
@@ -76,7 +76,7 @@ for vers in (2.7, 3.4, 3.5, 3.6):
|
|||||||
test_options[key] = (os.path.join(src_dir, pythonlib), PYOC, key, vers)
|
test_options[key] = (os.path.join(src_dir, pythonlib), PYOC, key, vers)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for vers in (1.5,
|
for vers in (1.4, 1.5,
|
||||||
2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
|
2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
|
||||||
3.0, 3.1, 3.2, 3.3,
|
3.0, 3.1, 3.2, 3.3,
|
||||||
3.4, 3.5, 3.6, 3.7, 'pypy3.2', 'pypy2.7'):
|
3.4, 3.5, 3.6, 3.7, 'pypy3.2', 'pypy2.7'):
|
||||||
|
@@ -45,6 +45,7 @@ Debugging Options:
|
|||||||
--asm -a include byte-code (disables --verify)
|
--asm -a include byte-code (disables --verify)
|
||||||
--grammar -g show matching grammar
|
--grammar -g show matching grammar
|
||||||
--tree -t include syntax tree (disables --verify)
|
--tree -t include syntax tree (disables --verify)
|
||||||
|
--tree++ add template rules to --tree when possible
|
||||||
|
|
||||||
Extensions of generated files:
|
Extensions of generated files:
|
||||||
'.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify)
|
'.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify)
|
||||||
@@ -60,7 +61,7 @@ from uncompyle6.version import VERSION
|
|||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print("""usage:
|
print("""usage:
|
||||||
%s [--verify | --weak-verify ] [--asm] [--tree] [--grammar] [-o <path>] FILE|DIR...
|
%s [--verify | --weak-verify ] [--asm] [--tree[+]] [--grammar] [-o <path>] FILE|DIR...
|
||||||
%s [--help | -h | --version | -V]
|
%s [--help | -h | --version | -V]
|
||||||
""" % (program, program))
|
""" % (program, program))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -84,8 +85,10 @@ def main_bin():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:',
|
opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:',
|
||||||
'help asm grammar linemaps recurse timestamp tree '
|
'help asm grammar linemaps recurse '
|
||||||
'fragments verify verify-run version weak-verify '
|
'timestamp tree tree+ '
|
||||||
|
'fragments verify verify-run version '
|
||||||
|
'weak-verify '
|
||||||
'showgrammar'.split(' '))
|
'showgrammar'.split(' '))
|
||||||
except getopt.GetoptError(e):
|
except getopt.GetoptError(e):
|
||||||
sys.stderr.write('%s: %s\n' % (os.path.basename(sys.argv[0]), e))
|
sys.stderr.write('%s: %s\n' % (os.path.basename(sys.argv[0]), e))
|
||||||
@@ -115,6 +118,9 @@ def main_bin():
|
|||||||
elif opt in ('--tree', '-t'):
|
elif opt in ('--tree', '-t'):
|
||||||
options['showast'] = True
|
options['showast'] = True
|
||||||
options['do_verify'] = None
|
options['do_verify'] = None
|
||||||
|
elif opt in ('--tree+',):
|
||||||
|
options['showast'] = 'Full'
|
||||||
|
options['do_verify'] = None
|
||||||
elif opt in ('--grammar', '-g'):
|
elif opt in ('--grammar', '-g'):
|
||||||
options['showgrammar'] = True
|
options['showgrammar'] = True
|
||||||
elif opt == '-o':
|
elif opt == '-o':
|
||||||
|
31
uncompyle6/parsers/parse14.py
Normal file
31
uncompyle6/parsers/parse14.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Copyright (c) 2018 Rocky Bernstein
|
||||||
|
|
||||||
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
|
from uncompyle6.parser import PythonParserSingle
|
||||||
|
from uncompyle6.parsers.parse15 import Python15Parser
|
||||||
|
|
||||||
|
class Python14Parser(Python15Parser):
|
||||||
|
|
||||||
|
def p_misc14(self, args):
|
||||||
|
"""
|
||||||
|
# Nothing here yet, but will need to add UNARY_CALL, BINARY_CALL,
|
||||||
|
# RAISE_EXCEPTION, BUILD_FUNCTION, UNPACK_ARG, UNPACK_VARARG, LOAD_LOCAL,
|
||||||
|
# SET_FUNC_ARGS, and RESERVE_FAST
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
|
||||||
|
super(Python14Parser, self).__init__(debug_parser)
|
||||||
|
self.customized = {}
|
||||||
|
|
||||||
|
|
||||||
|
class Python14ParserSingle(Python14Parser, PythonParserSingle):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Check grammar
|
||||||
|
p = Python14Parser()
|
||||||
|
p.check_grammar()
|
||||||
|
p.dump_grammar()
|
||||||
|
|
||||||
|
# local variables:
|
||||||
|
# tab-width: 4
|
@@ -23,7 +23,7 @@ class Python15Parser(Python21Parser):
|
|||||||
importlist ::= IMPORT_FROM
|
importlist ::= IMPORT_FROM
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Python15ParserSingle(Python21Parser, PythonParserSingle):
|
class Python15ParserSingle(Python15Parser, PythonParserSingle):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@@ -39,7 +39,7 @@ else:
|
|||||||
|
|
||||||
# The byte code versions we support.
|
# The byte code versions we support.
|
||||||
# Note: these all have to be floats
|
# Note: these all have to be floats
|
||||||
PYTHON_VERSIONS = frozenset((1.5,
|
PYTHON_VERSIONS = frozenset((1.4, 1.5,
|
||||||
2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
|
2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
|
||||||
3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7))
|
3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7))
|
||||||
|
|
||||||
@@ -121,7 +121,10 @@ class Scanner(object):
|
|||||||
|
|
||||||
# Offset: lineno pairs, only for offsets which start line.
|
# Offset: lineno pairs, only for offsets which start line.
|
||||||
# Locally we use list for more convenient iteration using indices
|
# Locally we use list for more convenient iteration using indices
|
||||||
|
if self.version > 1.4:
|
||||||
linestarts = list(self.opc.findlinestarts(code_obj))
|
linestarts = list(self.opc.findlinestarts(code_obj))
|
||||||
|
else:
|
||||||
|
linestarts = [[0, 1]]
|
||||||
self.linestarts = dict(linestarts)
|
self.linestarts = dict(linestarts)
|
||||||
|
|
||||||
# 'List-map' which shows line number of current op and offset of
|
# 'List-map' which shows line number of current op and offset of
|
||||||
|
36
uncompyle6/scanners/scanner14.py
Normal file
36
uncompyle6/scanners/scanner14.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Copyright (c) 2018 by Rocky Bernstein
|
||||||
|
"""
|
||||||
|
Python 1.4 bytecode decompiler massaging.
|
||||||
|
|
||||||
|
This massages tokenized 1.4 bytecode to make it more amenable for
|
||||||
|
grammar parsing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import uncompyle6.scanners.scanner15 as scan
|
||||||
|
# from uncompyle6.scanners.scanner26 import ingest as ingest26
|
||||||
|
|
||||||
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
|
from xdis.opcodes import opcode_14
|
||||||
|
JUMP_OPS = opcode_14.JUMP_OPS
|
||||||
|
|
||||||
|
# We base this off of 1.5 instead of the other way around
|
||||||
|
# because we cleaned things up this way.
|
||||||
|
# The history is that 2.7 support is the cleanest,
|
||||||
|
# then from that we got 2.6 and so on.
|
||||||
|
class Scanner14(scan.Scanner15):
|
||||||
|
def __init__(self, show_asm=False):
|
||||||
|
scan.Scanner15.__init__(self, show_asm)
|
||||||
|
self.opc = opcode_14
|
||||||
|
self.opname = opcode_14.opname
|
||||||
|
self.version = 1.4
|
||||||
|
self.genexpr_name = '<generator expression>'
|
||||||
|
return
|
||||||
|
|
||||||
|
# def ingest22(self, co, classname=None, code_objects={}, show_asm=None):
|
||||||
|
# tokens, customize = self.parent_ingest(co, classname, code_objects, show_asm)
|
||||||
|
# tokens = [t for t in tokens if t.kind != 'SET_LINENO']
|
||||||
|
|
||||||
|
# # for t in tokens:
|
||||||
|
# # print(t)
|
||||||
|
|
||||||
|
return tokens, customize
|
@@ -1,6 +1,6 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 1.5 bytecode decompiler scanner.
|
Python 1.5 bytecode decompiler massaging.
|
||||||
|
|
||||||
This massages tokenized 1.5 bytecode to make it more amenable for
|
This massages tokenized 1.5 bytecode to make it more amenable for
|
||||||
grammar parsing.
|
grammar parsing.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 2.1 bytecode scanner/deparser
|
Python 2.1 bytecode massaging.
|
||||||
|
|
||||||
This massages tokenized 2.1 bytecode to make it more amenable for
|
This massages tokenized 2.1 bytecode to make it more amenable for
|
||||||
grammar parsing.
|
grammar parsing.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 2.2 bytecode ingester.
|
Python 2.2 bytecode massaging.
|
||||||
|
|
||||||
This massages tokenized 2.2 bytecode to make it more amenable for
|
This massages tokenized 2.2 bytecode to make it more amenable for
|
||||||
grammar parsing.
|
grammar parsing.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 2.3 bytecode scanner/deparser
|
Python 2.3 bytecode massaging.
|
||||||
|
|
||||||
This massages tokenized 2.3 bytecode to make it more amenable for
|
This massages tokenized 2.3 bytecode to make it more amenable for
|
||||||
grammar parsing.
|
grammar parsing.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2017 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 2.4 bytecode scanner/deparser
|
Python 2.4 bytecode massaging.
|
||||||
|
|
||||||
This massages tokenized 2.7 bytecode to make it more amenable for
|
This massages tokenized 2.7 bytecode to make it more amenable for
|
||||||
grammar parsing.
|
grammar parsing.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Copyright (c) 2015-2017 by Rocky Bernstein
|
# Copyright (c) 2015-2018 by Rocky Bernstein
|
||||||
"""
|
"""
|
||||||
Python 2.5 bytecode scanner/deparser
|
Python 2.5 bytecode massaging.
|
||||||
|
|
||||||
This overlaps Python's 2.5's dis module, but it can be run from
|
This overlaps Python's 2.5's dis module, but it can be run from
|
||||||
Python 3 and other versions of Python. Also, we save token
|
Python 3 and other versions of Python. Also, we save token
|
||||||
|
@@ -1115,7 +1115,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
self.p.insts = p_insts
|
self.p.insts = p_insts
|
||||||
except (parser.ParserError(e), AssertionError(e)):
|
except (parser.ParserError(e), AssertionError(e)):
|
||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
maybe_show_tree(self.showast, ast)
|
maybe_show_tree(self, ast)
|
||||||
return ast
|
return ast
|
||||||
|
|
||||||
# The bytecode for the end of the main routine has a
|
# The bytecode for the end of the main routine has a
|
||||||
@@ -1154,7 +1154,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
except (parser.ParserError(e), AssertionError(e)):
|
except (parser.ParserError(e), AssertionError(e)):
|
||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
|
|
||||||
maybe_show_tree(self.showast, ast)
|
maybe_show_tree(self, ast)
|
||||||
|
|
||||||
checker(ast, False, self.ast_errors)
|
checker(ast, False, self.ast_errors)
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ def make_function3_annotate(self, node, is_lambda, nested=1,
|
|||||||
"""
|
"""
|
||||||
if default:
|
if default:
|
||||||
value = self.traverse(default, indent='')
|
value = self.traverse(default, indent='')
|
||||||
maybe_show_tree_param_default(self.showast, name, value)
|
maybe_show_tree_param_default(self, name, value)
|
||||||
result = '%s=%s' % (name, value)
|
result = '%s=%s' % (name, value)
|
||||||
if result[-2:] == '= ': # default was 'LOAD_CONST None'
|
if result[-2:] == '= ': # default was 'LOAD_CONST None'
|
||||||
result += 'None'
|
result += 'None'
|
||||||
|
@@ -251,6 +251,55 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def str_with_template(self, ast):
|
||||||
|
stream = sys.stdout
|
||||||
|
stream.write(self.str_with_template1(ast, '', None))
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
def str_with_template1(self, ast, indent, sibNum=None):
|
||||||
|
rv = str(ast.kind)
|
||||||
|
|
||||||
|
if sibNum is not None:
|
||||||
|
rv = "%2d. %s" % (sibNum, rv)
|
||||||
|
enumerate_children = False
|
||||||
|
if len(ast) > 1:
|
||||||
|
rv += " (%d)" % (len(ast))
|
||||||
|
enumerate_children = True
|
||||||
|
|
||||||
|
mapping = self._get_mapping(ast)
|
||||||
|
table = mapping[0]
|
||||||
|
key = ast
|
||||||
|
for i in mapping[1:]:
|
||||||
|
key = key[i]
|
||||||
|
pass
|
||||||
|
|
||||||
|
if key.kind in table:
|
||||||
|
rv += ": %s" % str(table[key.kind])
|
||||||
|
|
||||||
|
rv = indent + rv
|
||||||
|
indent += ' '
|
||||||
|
i = 0
|
||||||
|
for node in ast:
|
||||||
|
if hasattr(node, '__repr1__'):
|
||||||
|
if enumerate_children:
|
||||||
|
child = self.str_with_template1(node, indent, i)
|
||||||
|
else:
|
||||||
|
child = self.str_with_template1(node, indent, None)
|
||||||
|
else:
|
||||||
|
inst = node.format(line_prefix='L.')
|
||||||
|
if inst.startswith("\n"):
|
||||||
|
# Nuke leading \n
|
||||||
|
inst = inst[1:]
|
||||||
|
if enumerate_children:
|
||||||
|
child = indent + "%2d. %s" % (i, inst)
|
||||||
|
else:
|
||||||
|
child = indent + inst
|
||||||
|
pass
|
||||||
|
rv += "\n" + child
|
||||||
|
i += 1
|
||||||
|
return rv
|
||||||
|
|
||||||
|
|
||||||
def indent_if_source_nl(self, line_number, indent):
|
def indent_if_source_nl(self, line_number, indent):
|
||||||
if (line_number != self.line_number):
|
if (line_number != self.line_number):
|
||||||
self.write("\n" + self.indent + INDENT_PER_LEVEL[:-1])
|
self.write("\n" + self.indent + INDENT_PER_LEVEL[:-1])
|
||||||
@@ -2083,7 +2132,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
except AssertionError, e:
|
except AssertionError, e:
|
||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
maybe_show_tree(self.showast, ast)
|
maybe_show_tree(self, ast)
|
||||||
return ast
|
return ast
|
||||||
|
|
||||||
# The bytecode for the end of the main routine has a
|
# The bytecode for the end of the main routine has a
|
||||||
@@ -2116,7 +2165,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
except python_parser.ParserError, e:
|
except python_parser.ParserError, e:
|
||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
|
|
||||||
maybe_show_tree(self.showast, ast)
|
maybe_show_tree(self, ast)
|
||||||
|
|
||||||
checker(ast, False, self.ast_errors)
|
checker(ast, False, self.ast_errors)
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ def maybe_show_asm(showasm, tokens):
|
|||||||
stream.write('\n')
|
stream.write('\n')
|
||||||
|
|
||||||
|
|
||||||
def maybe_show_tree(show_tree, ast):
|
def maybe_show_tree(walker, ast):
|
||||||
"""
|
"""
|
||||||
Show the ast based on the showast flag (or file object), writing to the
|
Show the ast based on the showast flag (or file object), writing to the
|
||||||
appropriate stream depending on the type of the flag.
|
appropriate stream depending on the type of the flag.
|
||||||
@@ -45,11 +45,14 @@ def maybe_show_tree(show_tree, ast):
|
|||||||
like object, into which the ast will be written).
|
like object, into which the ast will be written).
|
||||||
:param ast: The ast to show.
|
:param ast: The ast to show.
|
||||||
"""
|
"""
|
||||||
if show_tree:
|
if walker.showast:
|
||||||
if hasattr(show_tree, 'write'):
|
if hasattr(walker.showast, 'write'):
|
||||||
stream = show_tree
|
stream = walker.showast
|
||||||
else:
|
else:
|
||||||
stream = sys.stdout
|
stream = sys.stdout
|
||||||
|
if walker.showast == 'Full':
|
||||||
|
walker.str_with_template(ast)
|
||||||
|
else:
|
||||||
stream.write(str(ast))
|
stream.write(str(ast))
|
||||||
stream.write('\n')
|
stream.write('\n')
|
||||||
|
|
||||||
|
@@ -12,4 +12,4 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# This file is suitable for sourcing inside bash as
|
# This file is suitable for sourcing inside bash as
|
||||||
# well as importing into Python
|
# well as importing into Python
|
||||||
VERSION='3.1.3'
|
VERSION='3.2.0'
|
||||||
|
Reference in New Issue
Block a user