mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2024-10-07 10:13:39 +00:00
Towards single compilation
This commit is contained in:
parent
2c7fcf9e62
commit
7e0526d627
22
pytest/test_single_compile.py
Normal file
22
pytest/test_single_compile.py
Normal file
@ -0,0 +1,22 @@
|
||||
import pytest
|
||||
from uncompyle6 import PYTHON_VERSION, PYTHON3, deparse_code
|
||||
|
||||
@pytest.mark.skip(reason="Reinstate when we have compiilation single")
|
||||
def test_single_mode():
|
||||
single_expressions = (
|
||||
'i = 1',
|
||||
'i and (j or k)',
|
||||
'i += 1',
|
||||
'i = j % 4',
|
||||
'i = {}',
|
||||
'i = []',
|
||||
'while i < 1 or stop:\n i\n',
|
||||
'while i < 1 or stop:\n print%s\n' % ('(i)' if PYTHON3 else ' i'),
|
||||
'for i in range(10):\n i\n',
|
||||
'for i in range(10):\n for j in range(10):\n i + j\n',
|
||||
'try:\n i\nexcept Exception:\n j\nelse:\n k\n'
|
||||
)
|
||||
|
||||
for expr in single_expressions:
|
||||
code = compile(expr + '\n', '<string>', 'single')
|
||||
assert deparse_code(PYTHON_VERSION, code, compile_mode='single').text == expr + '\n'
|
@ -76,10 +76,13 @@ def parse(p, tokens, customize):
|
||||
return ast
|
||||
|
||||
|
||||
def get_python_parser(version, debug_parser):
|
||||
def get_python_parser(version, debug_parser, compile_mode='exec'):
|
||||
"""
|
||||
Returns parser object for Python version 2 or 3
|
||||
depending on the parameter passed.
|
||||
depending on the parameter passed. *compile_mode*
|
||||
is either 'exec', 'eval', or 'single'. See
|
||||
https://docs.python.org/3.6/library/functions.html#compile for an explanation
|
||||
of the different modes.
|
||||
"""
|
||||
if version < 3.0:
|
||||
import uncompyle6.parsers.parse2 as parse2
|
||||
|
@ -209,10 +209,14 @@ class Python2Parser(PythonParser):
|
||||
load_attrs ::= load_attrs LOAD_ATTR
|
||||
'''
|
||||
|
||||
def p_grammar(self, args):
|
||||
def p_start(self, args):
|
||||
'''
|
||||
stmts ::= stmts sstmt
|
||||
stmts ::= sstmt
|
||||
'''
|
||||
|
||||
def p_grammar(self, args):
|
||||
'''
|
||||
sstmt ::= stmt
|
||||
sstmt ::= ifelsestmtr
|
||||
sstmt ::= return_stmt RETURN_LAST
|
||||
@ -710,3 +714,8 @@ class Python2Parser(PythonParser):
|
||||
else:
|
||||
raise Exception('unknown customize token %s' % k)
|
||||
self.addRule(rule, nop_func)
|
||||
|
||||
class Python2ParserSingle(Python2Parser):
|
||||
# Add:
|
||||
# call_stmt ::= expr PRINT_EXPR
|
||||
pass
|
||||
|
@ -818,3 +818,8 @@ class Python3Parser(PythonParser):
|
||||
% ('expr ' * token.attr, opname))
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
return
|
||||
|
||||
class Python3ParserSingle(Python3Parser):
|
||||
# Add:
|
||||
# call_stmt ::= expr PRINT_EXPR
|
||||
pass
|
||||
|
@ -487,7 +487,8 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
stacked_params = ('f', 'indent', 'isLambda', '_globals')
|
||||
|
||||
def __init__(self, version, out, scanner, showast=False,
|
||||
debug_parser=PARSER_DEFAULT_DEBUG):
|
||||
debug_parser=PARSER_DEFAULT_DEBUG,
|
||||
compile_mode='exec'):
|
||||
GenericASTTraversal.__init__(self, ast=None)
|
||||
self.scanner = scanner
|
||||
params = {
|
||||
@ -495,7 +496,8 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
'indent': '',
|
||||
}
|
||||
self.version = version
|
||||
self.p = get_python_parser(version, debug_parser=debug_parser)
|
||||
self.p = get_python_parser(version, debug_parser=debug_parser,
|
||||
compile_mode=compile_mode)
|
||||
self.debug_parser = dict(debug_parser)
|
||||
self.showast = showast
|
||||
self.params = params
|
||||
@ -1615,7 +1617,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
return ast
|
||||
|
||||
def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False,
|
||||
showgrammar=False, code_objects={}):
|
||||
showgrammar=False, code_objects={}, compile_mode='exec'):
|
||||
"""
|
||||
disassembles and deparses a given code block 'co'
|
||||
"""
|
||||
@ -1633,7 +1635,8 @@ def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False,
|
||||
debug_parser['reduce'] = showgrammar
|
||||
|
||||
# Build AST from disassembly.
|
||||
deparsed = SourceWalker(version, out, scanner, showast=showast, debug_parser=debug_parser)
|
||||
deparsed = SourceWalker(version, out, scanner, showast=showast,
|
||||
debug_parser=debug_parser, compile_mode=compile_mode)
|
||||
|
||||
deparsed.ast = deparsed.build_ast(tokens, customize)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user