diff --git a/uncompyle6/__init__.py b/uncompyle6/__init__.py index d3cf9bee..6294a553 100644 --- a/uncompyle6/__init__.py +++ b/uncompyle6/__init__.py @@ -47,7 +47,10 @@ import uncompyle6.semantics.pysource import uncompyle6.semantics.fragments # Export some functions -from uncompyle6.main import uncompyle_file +from uncompyle6.main import decompile_file + +# For compaitility +uncompyle_file = decompile_file # Conventience functions so you can say: # from uncompyle6 import deparse_code diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 23b25825..4d72b4da 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -11,7 +11,7 @@ from uncompyle6.linenumbers import line_number_mapping from xdis.load import load_module -def uncompyle( +def decompile( bytecode_version, co, out=None, showasm=None, showast=False, timestamp=None, showgrammar=False, code_objects={}, source_size=None, is_pypy=False, magic_int=None): @@ -48,8 +48,10 @@ def uncompyle( # deparsing failed raise pysource.SourceWalkerError(str(e)) +# For compatiblity +uncompyle = decompile -def uncompyle_file(filename, outstream=None, showasm=None, showast=False, +def decompile_file(filename, outstream=None, showasm=None, showast=False, showgrammar=False): """ decompile Python byte-code file (.pyc) @@ -62,16 +64,20 @@ def uncompyle_file(filename, outstream=None, showasm=None, showast=False, if type(co) == list: for con in co: - uncompyle(version, con, outstream, showasm, showast, + decompile(version, con, outstream, showasm, showast, timestamp, showgrammar, code_objects=code_objects, is_pypy=is_pypy, magic_int=magic_int) else: - uncompyle(version, co, outstream, showasm, showast, + decompile(version, co, outstream, showasm, showast, timestamp, showgrammar, code_objects=code_objects, source_size=source_size, is_pypy=is_pypy, magic_int=magic_int) co = None +# For compatiblity +uncompyle_file = decompile_file + + # FIXME: combine into an options parameter def main(in_base, out_base, files, codes, outfile=None, showasm=None, showast=False, do_verify=False, @@ -101,12 +107,6 @@ def main(in_base, out_base, files, codes, outfile=None, tot_files = okay_files = failed_files = verify_failed_files = 0 - # for code in codes: - # version = sys.version[:3] # "2.5" - # with open(code, "r") as f: - # co = compile(f.read(), "", "exec") - # uncompyle(sys.version[:3], co, sys.stdout, showasm=showasm, showast=showast) - for filename in files: infile = os.path.join(in_base, filename) if not os.path.exists(infile): @@ -142,7 +142,7 @@ def main(in_base, out_base, files, codes, outfile=None, # Try to uncompile the input file try: - uncompyle_file(infile, outstream, showasm, showast, showgrammar) + decompile_file(infile, outstream, showasm, showast, showgrammar) tot_files += 1 except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e: sys.stdout.write("\n") diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py new file mode 100644 index 00000000..1bc1668e --- /dev/null +++ b/uncompyle6/semantics/consts.py @@ -0,0 +1,347 @@ +# Copyright (c) 2017 by Rocky Bernstein +"""Constants used in pysource.py""" + +import re, sys +from uncompyle6.parsers.astnode import AST +from uncompyle6 import PYTHON3 +from uncompyle6.scanners.tok import Token, NoneToken + +if PYTHON3: + minint = -sys.maxsize-1 + maxint = sys.maxsize +else: + minint = -sys.maxint-1 + maxint = sys.maxint + + +LINE_LENGTH = 80 + +# Some ASTs used for comparing code fragments (like 'return None' at +# the end of functions). + +RETURN_LOCALS = AST('return_stmt', + [ AST('ret_expr', [AST('expr', [ Token('LOAD_LOCALS') ])]), + Token('RETURN_VALUE')]) + +NONE = AST('expr', [ NoneToken ] ) + +RETURN_NONE = AST('stmt', + [ AST('return_stmt', + [ NONE, Token('RETURN_VALUE')]) ]) + +PASS = AST('stmts', + [ AST('sstmt', + [ AST('stmt', + [ AST('passstmt', [])])])]) + +ASSIGN_DOC_STRING = lambda doc_string: \ + AST('stmt', + [ AST('assign', + [ AST('expr', [ Token('LOAD_CONST', pattr=doc_string) ]), + AST('designator', [ Token('STORE_NAME', pattr='__doc__')]) + ])]) + +NAME_MODULE = AST('stmt', + [ AST('assign', + [ AST('expr', + [Token('LOAD_NAME', pattr='__name__', offset=0, has_arg=True)]), + AST('designator', + [ Token('STORE_NAME', pattr='__module__', offset=3, has_arg=True)]) + ])]) + +# God intended \t, but Python has decided to use 4 spaces. +# If you want real tabs, use Go. +# TAB = '\t' +TAB = ' ' * 4 +INDENT_PER_LEVEL = ' ' # additional intent per pretty-print level + +TABLE_R = { + 'STORE_ATTR': ( '%c.%[1]{pattr}', 0), +# 'STORE_SUBSCR': ( '%c[%c]', 0, 1 ), + 'DELETE_ATTR': ( '%|del %c.%[-1]{pattr}\n', 0 ), +# 'EXEC_STMT': ( '%|exec %c in %[1]C\n', 0, (0,maxint,', ') ), +} + +TABLE_R0 = { +# 'BUILD_LIST': ( '[%C]', (0,-1,', ') ), +# 'BUILD_TUPLE': ( '(%C)', (0,-1,', ') ), +# 'CALL_FUNCTION': ( '%c(%P)', 0, (1,-1,', ') ), +} +TABLE_DIRECT = { + 'BINARY_ADD': ( '+' ,), + 'BINARY_SUBTRACT': ( '-' ,), + 'BINARY_MULTIPLY': ( '*' ,), + 'BINARY_DIVIDE': ( '/' ,), + 'BINARY_MATRIX_MULTIPLY': ( '@' ,), + 'BINARY_TRUE_DIVIDE': ( '/' ,), + 'BINARY_FLOOR_DIVIDE': ( '//' ,), + 'BINARY_MODULO': ( '%%',), + 'BINARY_POWER': ( '**',), + 'BINARY_LSHIFT': ( '<<',), + 'BINARY_RSHIFT': ( '>>',), + 'BINARY_AND': ( '&' ,), + 'BINARY_OR': ( '|' ,), + 'BINARY_XOR': ( '^' ,), + 'INPLACE_ADD': ( '+=' ,), + 'INPLACE_SUBTRACT': ( '-=' ,), + 'INPLACE_MULTIPLY': ( '*=' ,), + 'INPLACE_MATRIX_MULTIPLY': ( '@=' ,), + 'INPLACE_DIVIDE': ( '/=' ,), + 'INPLACE_TRUE_DIVIDE': ( '/=' ,), + 'INPLACE_FLOOR_DIVIDE': ( '//=' ,), + 'INPLACE_MODULO': ( '%%=',), + 'INPLACE_POWER': ( '**=',), + 'INPLACE_LSHIFT': ( '<<=',), + 'INPLACE_RSHIFT': ( '>>=',), + 'INPLACE_AND': ( '&=' ,), + 'INPLACE_OR': ( '|=' ,), + 'INPLACE_XOR': ( '^=' ,), + 'binary_expr': ( '%c %c %c', 0, -1, 1 ), + + 'UNARY_POSITIVE': ( '+',), + 'UNARY_NEGATIVE': ( '-',), + 'UNARY_INVERT': ( '~%c'), + 'unary_expr': ( '%c%c', 1, 0), + + 'unary_not': ( 'not %c', 0 ), + 'unary_convert': ( '`%c`', 0 ), + 'get_iter': ( 'iter(%c)', 0 ), + 'slice0': ( '%c[:]', 0 ), + 'slice1': ( '%c[%p:]', 0, (1, 100) ), + 'slice2': ( '%c[:%p]', 0, (1, 100) ), + 'slice3': ( '%c[%p:%p]', 0, (1, 100), (2, 100) ), + + 'IMPORT_FROM': ( '%{pattr}', ), + 'load_attr': ( '%c.%[1]{pattr}', 0), + 'LOAD_FAST': ( '%{pattr}', ), + 'LOAD_NAME': ( '%{pattr}', ), + 'LOAD_CLASSNAME': ( '%{pattr}', ), + 'LOAD_GLOBAL': ( '%{pattr}', ), + 'LOAD_DEREF': ( '%{pattr}', ), + 'LOAD_LOCALS': ( 'locals()', ), + 'LOAD_ASSERT': ( '%{pattr}', ), +# 'LOAD_CONST': ( '%{pattr}', ), # handled by n_LOAD_CONST + 'DELETE_FAST': ( '%|del %{pattr}\n', ), + 'DELETE_NAME': ( '%|del %{pattr}\n', ), + 'DELETE_GLOBAL': ( '%|del %{pattr}\n', ), + 'delete_subscr': ( '%|del %c[%c]\n', 0, 1,), + 'binary_subscr': ( '%c[%p]', 0, (1, 100)), + 'binary_subscr2': ( '%c[%p]', 0, (1, 100)), + 'store_subscr': ( '%c[%c]', 0, 1), + 'STORE_FAST': ( '%{pattr}', ), + 'STORE_NAME': ( '%{pattr}', ), + 'STORE_GLOBAL': ( '%{pattr}', ), + 'STORE_DEREF': ( '%{pattr}', ), + 'unpack': ( '%C%,', (1, maxint, ', ') ), + + # This nonterminal we create on the fly in semantic routines + 'unpack_w_parens': ( '(%C%,)', (1, maxint, ', ') ), + + 'unpack_list': ( '[%C]', (1, maxint, ', ') ), + 'build_tuple2': ( '%P', (0, -1, ', ', 100) ), + + # 'list_compr': ( '[ %c ]', -2), # handled by n_list_compr + 'list_iter': ( '%c', 0), + 'list_for': ( ' for %c in %c%c', 2, 0, 3 ), + 'list_if': ( ' if %c%c', 0, 2 ), + 'list_if_not': ( ' if not %p%c', (0, 22), 2 ), + 'lc_body': ( '', ), # ignore when recusing + + 'comp_iter': ( '%c', 0), + 'comp_if': ( ' if %c%c', 0, 2 ), + 'comp_ifnot': ( ' if not %p%c', (0, 22), 2 ), + 'comp_body': ( '', ), # ignore when recusing + 'set_comp_body': ( '%c', 0 ), + 'gen_comp_body': ( '%c', 0 ), + 'dict_comp_body': ( '%c:%c', 1, 0 ), + + 'assign': ( '%|%c = %p\n', -1, (0, 200) ), + + # The 2nd parameter should have a = suffix. + # There is a rule with a 4th parameter "designator" + # which we don't use here. + 'augassign1': ( '%|%c %c %c\n', 0, 2, 1), + + 'augassign2': ( '%|%c.%[2]{pattr} %c %c\n', 0, -3, -4), + 'designList': ( '%c = %c', 0, -1 ), + 'and': ( '%c and %c', 0, 2 ), + 'ret_and': ( '%c and %c', 0, 2 ), + 'and2': ( '%c', 3 ), + 'or': ( '%c or %c', 0, 2 ), + 'ret_or': ( '%c or %c', 0, 2 ), + 'conditional': ( '%p if %p else %p', (2, 27), (0, 27), (4, 27)), + 'ret_cond': ( '%p if %p else %p', (2, 27), (0, 27), (-1, 27)), + 'conditionalnot': ( '%p if not %p else %p', (2, 27), (0, 22), (4, 27)), + 'ret_cond_not': ( '%p if not %p else %p', (2, 27), (0, 22), (-1, 27)), + 'conditional_lambda': ( '(%c if %c else %c)', 2, 0, 3), + 'return_lambda': ('%c', 0), + 'compare': ( '%p %[-1]{pattr} %p', (0, 19), (1, 19) ), + 'cmp_list': ( '%p %p', (0, 20), (1, 19)), + 'cmp_list1': ( '%[3]{pattr} %p %p', (0, 19), (-2, 19)), + 'cmp_list2': ( '%[1]{pattr} %p', (0, 19)), +# 'classdef': (), # handled by n_classdef() + 'funcdef': ( '\n\n%|def %c\n', -2), # -2 to handle closures + 'funcdefdeco': ( '\n\n%c', 0), + 'mkfuncdeco': ( '%|@%c\n%c', 0, 1), + 'mkfuncdeco0': ( '%|def %c\n', 0), + 'classdefdeco': ( '\n\n%c', 0), + 'classdefdeco1': ( '%|@%c\n%c', 0, 1), + 'kwarg': ( '%[0]{pattr}=%c', 1), + 'kwargs': ( '%D', (0, maxint, ', ') ), + + 'assert_expr_or': ( '%c or %c', 0, 2 ), + 'assert_expr_and': ( '%c and %c', 0, 2 ), + 'print_items_stmt': ( '%|print %c%c,\n', 0, 2), # Python 2 only + 'print_items_nl_stmt': ( '%|print %c%c\n', 0, 2), + 'print_item': ( ', %c', 0), + 'print_nl': ( '%|print\n', ), + 'print_to': ( '%|print >> %c, %c,\n', 0, 1 ), + 'print_to_nl': ( '%|print >> %c, %c\n', 0, 1 ), + 'print_nl_to': ( '%|print >> %c\n', 0 ), + 'print_to_items': ( '%C', (0, 2, ', ') ), + + 'call_stmt': ( '%|%p\n', (0, 200)), + 'break_stmt': ( '%|break\n', ), + 'continue_stmt': ( '%|continue\n', ), + + 'raise_stmt0': ( '%|raise\n', ), + 'raise_stmt1': ( '%|raise %c\n', 0), + 'raise_stmt3': ( '%|raise %c, %c, %c\n', 0, 1, 2), +# 'yield': ( 'yield %c', 0), +# 'return_stmt': ( '%|return %c\n', 0), + + 'ifstmt': ( '%|if %c:\n%+%c%-', 0, 1 ), + 'iflaststmt': ( '%|if %c:\n%+%c%-', 0, 1 ), + 'iflaststmtl': ( '%|if %c:\n%+%c%-', 0, 1 ), + 'testtrue': ( 'not %p', (0, 22) ), + + 'ifelsestmt': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), + 'ifelsestmtc': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), + 'ifelsestmtl': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), + 'ifelifstmt': ( '%|if %c:\n%+%c%-%c', 0, 1, 3 ), + 'elifelifstmt': ( '%|elif %c:\n%+%c%-%c', 0, 1, 3 ), + 'elifstmt': ( '%|elif %c:\n%+%c%-', 0, 1 ), + 'elifelsestmt': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), + 'ifelsestmtr': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 2 ), + 'elifelsestmtr': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-\n\n', 0, 1, 2 ), + + 'whileTruestmt': ( '%|while True:\n%+%c%-\n\n', 1 ), + 'whilestmt': ( '%|while %c:\n%+%c%-\n\n', 1, 2 ), + 'while1stmt': ( '%|while 1:\n%+%c%-\n\n', 1 ), + 'while1elsestmt': ( '%|while 1:\n%+%c%-%|else:\n%+%c%-\n\n', 1, -2 ), + 'whileelsestmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n', 1, 2, -2 ), + 'whileelselaststmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-', 1, 2, -2 ), + 'forstmt': ( '%|for %c in %c:\n%+%c%-\n\n', 3, 1, 4 ), + 'forelsestmt': ( + '%|for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n', 3, 1, 4, -2), + 'forelselaststmt': ( + '%|for %c in %c:\n%+%c%-%|else:\n%+%c%-', 3, 1, 4, -2), + 'forelselaststmtl': ( + '%|for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n', 3, 1, 4, -2), + 'trystmt': ( '%|try:\n%+%c%-%c\n\n', 1, 3 ), + 'tryelsestmt': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-\n\n', 1, 3, 4 ), + 'tryelsestmtc': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ), + 'tryelsestmtl': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ), + 'tf_trystmt': ( '%c%-%c%+', 1, 3 ), + 'tf_tryelsestmt': ( '%c%-%c%|else:\n%+%c', 1, 3, 4 ), + 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 5 ), + 'except': ( '%|except:\n%+%c%-', 3 ), + 'except_cond1': ( '%|except %c:\n', 1 ), + 'except_suite': ( '%+%c%-%C', 0, (1, maxint, '') ), + 'except_suite_finalize': ( '%+%c%-%C', 1, (3, maxint, '') ), + 'withstmt': ( '%|with %c:\n%+%c%-', 0, 3), + 'withasstmt': ( '%|with %c as %c:\n%+%c%-', 0, 2, 3), + 'passstmt': ( '%|pass\n', ), + 'STORE_FAST': ( '%{pattr}', ), + 'kv': ( '%c: %c', 3, 1 ), + 'kv2': ( '%c: %c', 1, 2 ), + 'mapexpr': ( '{%[1]C}', (0, maxint, ', ') ), + 'importstmt': ( '%|import %c\n', 2), + 'importfrom': ( '%|from %[2]{pattr} import %c\n', 3 ), + 'importstar': ( '%|from %[2]{pattr} import *\n', ), +} + + +MAP_DIRECT = (TABLE_DIRECT, ) +MAP_R0 = (TABLE_R0, -1, 0) +MAP_R = (TABLE_R, -1) + +MAP = { + 'stmt': MAP_R, + 'call_function': MAP_R, + 'del_stmt': MAP_R, + 'designator': MAP_R, + 'exprlist': MAP_R0, +} + +PRECEDENCE = { + 'build_list': 0, + 'mapexpr': 0, + 'unary_convert': 0, + 'dictcomp': 0, + 'setcomp': 0, + 'list_compr': 0, + 'genexpr': 0, + + 'load_attr': 2, + 'binary_subscr': 2, + 'binary_subscr2': 2, + 'slice0': 2, + 'slice1': 2, + 'slice2': 2, + 'slice3': 2, + 'buildslice2': 2, + 'buildslice3': 2, + 'call_function': 2, + + 'BINARY_POWER': 4, + + 'unary_expr': 6, + + 'BINARY_MULTIPLY': 8, + 'BINARY_DIVIDE': 8, + 'BINARY_TRUE_DIVIDE': 8, + 'BINARY_FLOOR_DIVIDE': 8, + 'BINARY_MODULO': 8, + + 'BINARY_ADD': 10, + 'BINARY_SUBTRACT': 10, + + 'BINARY_LSHIFT': 12, + 'BINARY_RSHIFT': 12, + + 'BINARY_AND': 14, + + 'BINARY_XOR': 16, + + 'BINARY_OR': 18, + + 'cmp': 20, + + 'unary_not': 22, + + 'and': 24, + 'ret_and': 24, + + 'or': 26, + 'ret_or': 26, + + 'conditional': 28, + 'conditionalnot': 28, + 'ret_cond': 28, + 'ret_cond_not': 28, + + '_mklambda': 30, + 'yield': 101, + 'yield_from': 101 +} + +ASSIGN_TUPLE_PARAM = lambda param_name: \ + AST('expr', [ Token('LOAD_FAST', pattr=param_name) ]) + +escape = re.compile(r''' + (?P [^%]* ) + % ( \[ (?P -? \d+ ) \] )? + ((?P [^{] ) | + ( [{] (?P [^}]* ) [}] )) + ''', re.VERBOSE) diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index 8c14fd75..aaa9cb8d 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -69,17 +69,22 @@ from uncompyle6.show import ( maybe_show_ast_param_default, ) -from uncompyle6.semantics.pysource import AST, INDENT_PER_LEVEL, NONE, PRECEDENCE, \ - ParserError, TABLE_DIRECT, escape, find_globals, minint, MAP +from uncompyle6.parsers.astnode import AST + +from uncompyle6.semantics.pysource import ( + ParserError, find_globals, StringIO) + +from uncompyle6.semantics.consts import ( + INDENT_PER_LEVEL, NONE, PRECEDENCE, + TABLE_DIRECT, escape, minint, MAP + ) from uncompyle6.semantics.make_function import find_all_globals, find_none if PYTHON3: from itertools import zip_longest - from io import StringIO else: from itertools import izip_longest as zip_longest - from StringIO import StringIO from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 649f7ed0..57d80f08 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -60,7 +60,7 @@ methods implement most of the below. %{...} evaluate ... in context of N %% literal '%' %p evaluate N setting precedence -n + * indicates an argument (A) required. @@ -69,7 +69,7 @@ n """ from __future__ import print_function -import sys, re +import sys from uncompyle6 import PYTHON3 from xdis.code import iscode @@ -79,13 +79,20 @@ from uncompyle6.parser import get_python_parser from uncompyle6.parsers.astnode import AST from spark_parser import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from uncompyle6.scanner import Code, get_scanner -from uncompyle6.scanners.tok import Token, NoneToken import uncompyle6.parser as python_parser from uncompyle6.semantics.make_function import ( make_function2, make_function3, make_function3_annotate, find_globals) from uncompyle6.semantics.parser_error import ParserError from uncompyle6.semantics.check_ast import checker from uncompyle6.semantics.helper import print_docstring +from uncompyle6.scanners.tok import Token + +from uncompyle6.semantics.consts import ( + LINE_LENGTH, RETURN_LOCALS, NONE, RETURN_NONE, PASS, + ASSIGN_DOC_STRING, NAME_MODULE, TAB, + INDENT_PER_LEVEL, TABLE_R, TABLE_DIRECT, MAP_DIRECT, + MAP, PRECEDENCE, ASSIGN_TUPLE_PARAM, escape, maxint, minint) + from uncompyle6.show import ( maybe_show_ast, @@ -93,348 +100,8 @@ from uncompyle6.show import ( if PYTHON3: from io import StringIO - minint = -sys.maxsize-1 - maxint = sys.maxsize else: from StringIO import StringIO - minint = -sys.maxint-1 - maxint = sys.maxint - -LINE_LENGTH = 80 - -# Some ASTs used for comparing code fragments (like 'return None' at -# the end of functions). - -RETURN_LOCALS = AST('return_stmt', - [ AST('ret_expr', [AST('expr', [ Token('LOAD_LOCALS') ])]), - Token('RETURN_VALUE')]) - -NONE = AST('expr', [ NoneToken ] ) - -RETURN_NONE = AST('stmt', - [ AST('return_stmt', - [ NONE, Token('RETURN_VALUE')]) ]) - -PASS = AST('stmts', - [ AST('sstmt', - [ AST('stmt', - [ AST('passstmt', [])])])]) - -ASSIGN_DOC_STRING = lambda doc_string: \ - AST('stmt', - [ AST('assign', - [ AST('expr', [ Token('LOAD_CONST', pattr=doc_string) ]), - AST('designator', [ Token('STORE_NAME', pattr='__doc__')]) - ])]) - -BUILD_TUPLE_0 = AST('expr', - [ AST('build_list', - [ Token('BUILD_TUPLE_0') ])]) - -NAME_MODULE = AST('stmt', - [ AST('assign', - [ AST('expr', - [Token('LOAD_NAME', pattr='__name__', offset=0, has_arg=True)]), - AST('designator', - [ Token('STORE_NAME', pattr='__module__', offset=3, has_arg=True)]) - ])]) - -# God intended \t, but Python has decided to use 4 spaces. -# If you want real tabs, use Go. -# TAB = '\t' -TAB = ' ' * 4 -INDENT_PER_LEVEL = ' ' # additional intent per pretty-print level - -TABLE_R = { - 'STORE_ATTR': ( '%c.%[1]{pattr}', 0), -# 'STORE_SUBSCR': ( '%c[%c]', 0, 1 ), - 'DELETE_ATTR': ( '%|del %c.%[-1]{pattr}\n', 0 ), -# 'EXEC_STMT': ( '%|exec %c in %[1]C\n', 0, (0,maxint,', ') ), -} - -TABLE_R0 = { -# 'BUILD_LIST': ( '[%C]', (0,-1,', ') ), -# 'BUILD_TUPLE': ( '(%C)', (0,-1,', ') ), -# 'CALL_FUNCTION': ( '%c(%P)', 0, (1,-1,', ') ), -} -TABLE_DIRECT = { - 'BINARY_ADD': ( '+' ,), - 'BINARY_SUBTRACT': ( '-' ,), - 'BINARY_MULTIPLY': ( '*' ,), - 'BINARY_DIVIDE': ( '/' ,), - 'BINARY_MATRIX_MULTIPLY': ( '@' ,), - 'BINARY_TRUE_DIVIDE': ( '/' ,), - 'BINARY_FLOOR_DIVIDE': ( '//' ,), - 'BINARY_MODULO': ( '%%',), - 'BINARY_POWER': ( '**',), - 'BINARY_LSHIFT': ( '<<',), - 'BINARY_RSHIFT': ( '>>',), - 'BINARY_AND': ( '&' ,), - 'BINARY_OR': ( '|' ,), - 'BINARY_XOR': ( '^' ,), - 'INPLACE_ADD': ( '+=' ,), - 'INPLACE_SUBTRACT': ( '-=' ,), - 'INPLACE_MULTIPLY': ( '*=' ,), - 'INPLACE_MATRIX_MULTIPLY': ( '@=' ,), - 'INPLACE_DIVIDE': ( '/=' ,), - 'INPLACE_TRUE_DIVIDE': ( '/=' ,), - 'INPLACE_FLOOR_DIVIDE': ( '//=' ,), - 'INPLACE_MODULO': ( '%%=',), - 'INPLACE_POWER': ( '**=',), - 'INPLACE_LSHIFT': ( '<<=',), - 'INPLACE_RSHIFT': ( '>>=',), - 'INPLACE_AND': ( '&=' ,), - 'INPLACE_OR': ( '|=' ,), - 'INPLACE_XOR': ( '^=' ,), - 'binary_expr': ( '%c %c %c', 0, -1, 1 ), - - 'UNARY_POSITIVE': ( '+',), - 'UNARY_NEGATIVE': ( '-',), - 'UNARY_INVERT': ( '~%c'), - 'unary_expr': ( '%c%c', 1, 0), - - 'unary_not': ( 'not %c', 0 ), - 'unary_convert': ( '`%c`', 0 ), - 'get_iter': ( 'iter(%c)', 0 ), - 'slice0': ( '%c[:]', 0 ), - 'slice1': ( '%c[%p:]', 0, (1, 100) ), - 'slice2': ( '%c[:%p]', 0, (1, 100) ), - 'slice3': ( '%c[%p:%p]', 0, (1, 100), (2, 100) ), - - 'IMPORT_FROM': ( '%{pattr}', ), - 'load_attr': ( '%c.%[1]{pattr}', 0), - 'LOAD_FAST': ( '%{pattr}', ), - 'LOAD_NAME': ( '%{pattr}', ), - 'LOAD_CLASSNAME': ( '%{pattr}', ), - 'LOAD_GLOBAL': ( '%{pattr}', ), - 'LOAD_DEREF': ( '%{pattr}', ), - 'LOAD_LOCALS': ( 'locals()', ), - 'LOAD_ASSERT': ( '%{pattr}', ), -# 'LOAD_CONST': ( '%{pattr}', ), # handled by n_LOAD_CONST - 'DELETE_FAST': ( '%|del %{pattr}\n', ), - 'DELETE_NAME': ( '%|del %{pattr}\n', ), - 'DELETE_GLOBAL': ( '%|del %{pattr}\n', ), - 'delete_subscr': ( '%|del %c[%c]\n', 0, 1,), - 'binary_subscr': ( '%c[%p]', 0, (1, 100)), - 'binary_subscr2': ( '%c[%p]', 0, (1, 100)), - 'store_subscr': ( '%c[%c]', 0, 1), - 'STORE_FAST': ( '%{pattr}', ), - 'STORE_NAME': ( '%{pattr}', ), - 'STORE_GLOBAL': ( '%{pattr}', ), - 'STORE_DEREF': ( '%{pattr}', ), - 'unpack': ( '%C%,', (1, maxint, ', ') ), - - # This nonterminal we create on the fly in semantic routines - 'unpack_w_parens': ( '(%C%,)', (1, maxint, ', ') ), - - 'unpack_list': ( '[%C]', (1, maxint, ', ') ), - 'build_tuple2': ( '%P', (0, -1, ', ', 100) ), - - # 'list_compr': ( '[ %c ]', -2), # handled by n_list_compr - 'list_iter': ( '%c', 0), - 'list_for': ( ' for %c in %c%c', 2, 0, 3 ), - 'list_if': ( ' if %c%c', 0, 2 ), - 'list_if_not': ( ' if not %p%c', (0, 22), 2 ), - 'lc_body': ( '', ), # ignore when recusing - - 'comp_iter': ( '%c', 0), - 'comp_if': ( ' if %c%c', 0, 2 ), - 'comp_ifnot': ( ' if not %p%c', (0, 22), 2 ), - 'comp_body': ( '', ), # ignore when recusing - 'set_comp_body': ( '%c', 0 ), - 'gen_comp_body': ( '%c', 0 ), - 'dict_comp_body': ( '%c:%c', 1, 0 ), - - 'assign': ( '%|%c = %p\n', -1, (0, 200) ), - - # The 2nd parameter should have a = suffix. - # There is a rule with a 4th parameter "designator" - # which we don't use here. - 'augassign1': ( '%|%c %c %c\n', 0, 2, 1), - - 'augassign2': ( '%|%c.%[2]{pattr} %c %c\n', 0, -3, -4), - 'designList': ( '%c = %c', 0, -1 ), - 'and': ( '%c and %c', 0, 2 ), - 'ret_and': ( '%c and %c', 0, 2 ), - 'and2': ( '%c', 3 ), - 'or': ( '%c or %c', 0, 2 ), - 'ret_or': ( '%c or %c', 0, 2 ), - 'conditional': ( '%p if %p else %p', (2, 27), (0, 27), (4, 27)), - 'ret_cond': ( '%p if %p else %p', (2, 27), (0, 27), (-1, 27)), - 'conditionalnot': ( '%p if not %p else %p', (2, 27), (0, 22), (4, 27)), - 'ret_cond_not': ( '%p if not %p else %p', (2, 27), (0, 22), (-1, 27)), - 'conditional_lambda': ( '(%c if %c else %c)', 2, 0, 3), - 'return_lambda': ('%c', 0), - 'compare': ( '%p %[-1]{pattr} %p', (0, 19), (1, 19) ), - 'cmp_list': ( '%p %p', (0, 20), (1, 19)), - 'cmp_list1': ( '%[3]{pattr} %p %p', (0, 19), (-2, 19)), - 'cmp_list2': ( '%[1]{pattr} %p', (0, 19)), -# 'classdef': (), # handled by n_classdef() - 'funcdef': ( '\n\n%|def %c\n', -2), # -2 to handle closures - 'funcdefdeco': ( '\n\n%c', 0), - 'mkfuncdeco': ( '%|@%c\n%c', 0, 1), - 'mkfuncdeco0': ( '%|def %c\n', 0), - 'classdefdeco': ( '\n\n%c', 0), - 'classdefdeco1': ( '%|@%c\n%c', 0, 1), - 'kwarg': ( '%[0]{pattr}=%c', 1), - 'kwargs': ( '%D', (0, maxint, ', ') ), - - 'assert_expr_or': ( '%c or %c', 0, 2 ), - 'assert_expr_and': ( '%c and %c', 0, 2 ), - 'print_items_stmt': ( '%|print %c%c,\n', 0, 2), # Python 2 only - 'print_items_nl_stmt': ( '%|print %c%c\n', 0, 2), - 'print_item': ( ', %c', 0), - 'print_nl': ( '%|print\n', ), - 'print_to': ( '%|print >> %c, %c,\n', 0, 1 ), - 'print_to_nl': ( '%|print >> %c, %c\n', 0, 1 ), - 'print_nl_to': ( '%|print >> %c\n', 0 ), - 'print_to_items': ( '%C', (0, 2, ', ') ), - - 'call_stmt': ( '%|%p\n', (0, 200)), - 'break_stmt': ( '%|break\n', ), - 'continue_stmt': ( '%|continue\n', ), - - 'raise_stmt0': ( '%|raise\n', ), - 'raise_stmt1': ( '%|raise %c\n', 0), - 'raise_stmt3': ( '%|raise %c, %c, %c\n', 0, 1, 2), -# 'yield': ( 'yield %c', 0), -# 'return_stmt': ( '%|return %c\n', 0), - - 'ifstmt': ( '%|if %c:\n%+%c%-', 0, 1 ), - 'iflaststmt': ( '%|if %c:\n%+%c%-', 0, 1 ), - 'iflaststmtl': ( '%|if %c:\n%+%c%-', 0, 1 ), - 'testtrue': ( 'not %p', (0, 22) ), - - 'ifelsestmt': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), - 'ifelsestmtc': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), - 'ifelsestmtl': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), - 'ifelifstmt': ( '%|if %c:\n%+%c%-%c', 0, 1, 3 ), - 'elifelifstmt': ( '%|elif %c:\n%+%c%-%c', 0, 1, 3 ), - 'elifstmt': ( '%|elif %c:\n%+%c%-', 0, 1 ), - 'elifelsestmt': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ), - 'ifelsestmtr': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 2 ), - 'elifelsestmtr': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-\n\n', 0, 1, 2 ), - - 'whileTruestmt': ( '%|while True:\n%+%c%-\n\n', 1 ), - 'whilestmt': ( '%|while %c:\n%+%c%-\n\n', 1, 2 ), - 'while1stmt': ( '%|while 1:\n%+%c%-\n\n', 1 ), - 'while1elsestmt': ( '%|while 1:\n%+%c%-%|else:\n%+%c%-\n\n', 1, -2 ), - 'whileelsestmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n', 1, 2, -2 ), - 'whileelselaststmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-', 1, 2, -2 ), - 'forstmt': ( '%|for %c in %c:\n%+%c%-\n\n', 3, 1, 4 ), - 'forelsestmt': ( - '%|for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n', 3, 1, 4, -2), - 'forelselaststmt': ( - '%|for %c in %c:\n%+%c%-%|else:\n%+%c%-', 3, 1, 4, -2), - 'forelselaststmtl': ( - '%|for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n', 3, 1, 4, -2), - 'trystmt': ( '%|try:\n%+%c%-%c\n\n', 1, 3 ), - 'tryelsestmt': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-\n\n', 1, 3, 4 ), - 'tryelsestmtc': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ), - 'tryelsestmtl': ( '%|try:\n%+%c%-%c%|else:\n%+%c%-', 1, 3, 4 ), - 'tf_trystmt': ( '%c%-%c%+', 1, 3 ), - 'tf_tryelsestmt': ( '%c%-%c%|else:\n%+%c', 1, 3, 4 ), - 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 5 ), - 'except': ( '%|except:\n%+%c%-', 3 ), - 'except_cond1': ( '%|except %c:\n', 1 ), - 'except_suite': ( '%+%c%-%C', 0, (1, maxint, '') ), - 'except_suite_finalize': ( '%+%c%-%C', 1, (3, maxint, '') ), - 'withstmt': ( '%|with %c:\n%+%c%-', 0, 3), - 'withasstmt': ( '%|with %c as %c:\n%+%c%-', 0, 2, 3), - 'passstmt': ( '%|pass\n', ), - 'STORE_FAST': ( '%{pattr}', ), - 'kv': ( '%c: %c', 3, 1 ), - 'kv2': ( '%c: %c', 1, 2 ), - 'mapexpr': ( '{%[1]C}', (0, maxint, ', ') ), - 'importstmt': ( '%|import %c\n', 2), - 'importfrom': ( '%|from %[2]{pattr} import %c\n', 3 ), - 'importstar': ( '%|from %[2]{pattr} import *\n', ), -} - - -MAP_DIRECT = (TABLE_DIRECT, ) -MAP_R0 = (TABLE_R0, -1, 0) -MAP_R = (TABLE_R, -1) - -MAP = { - 'stmt': MAP_R, - 'call_function': MAP_R, - 'del_stmt': MAP_R, - 'designator': MAP_R, - 'exprlist': MAP_R0, -} - -PRECEDENCE = { - 'build_list': 0, - 'mapexpr': 0, - 'unary_convert': 0, - 'dictcomp': 0, - 'setcomp': 0, - 'list_compr': 0, - 'genexpr': 0, - - 'load_attr': 2, - 'binary_subscr': 2, - 'binary_subscr2': 2, - 'slice0': 2, - 'slice1': 2, - 'slice2': 2, - 'slice3': 2, - 'buildslice2': 2, - 'buildslice3': 2, - 'call_function': 2, - - 'BINARY_POWER': 4, - - 'unary_expr': 6, - - 'BINARY_MULTIPLY': 8, - 'BINARY_DIVIDE': 8, - 'BINARY_TRUE_DIVIDE': 8, - 'BINARY_FLOOR_DIVIDE': 8, - 'BINARY_MODULO': 8, - - 'BINARY_ADD': 10, - 'BINARY_SUBTRACT': 10, - - 'BINARY_LSHIFT': 12, - 'BINARY_RSHIFT': 12, - - 'BINARY_AND': 14, - - 'BINARY_XOR': 16, - - 'BINARY_OR': 18, - - 'cmp': 20, - - 'unary_not': 22, - - 'and': 24, - 'ret_and': 24, - - 'or': 26, - 'ret_or': 26, - - 'conditional': 28, - 'conditionalnot': 28, - 'ret_cond': 28, - 'ret_cond_not': 28, - - '_mklambda': 30, - 'yield': 101, - 'yield_from': 101 -} - -ASSIGN_TUPLE_PARAM = lambda param_name: \ - AST('expr', [ Token('LOAD_FAST', pattr=param_name) ]) - -escape = re.compile(r''' - (?P [^%]* ) - % ( \[ (?P -? \d+ ) \] )? - ((?P [^{] ) | - ( [{] (?P [^}]* ) [}] )) - ''', re.VERBOSE) def is_docstring(node): try: