diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 60e72847..e4aca991 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -265,10 +265,14 @@ class PythonParser(GenericASTBuilder): def p_augmented_assign(self, args): ''' - stmt ::= augassign0 stmt ::= augassign1 stmt ::= augassign2 - augassign0 ::= expr expr inplace_op designator + + # This is odd in that other augassign1's have only 3 slots + # The designator isn't used as that's supposed to be also + # indicated in the first expr + augassign1 ::= expr expr inplace_op designator + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SUBSCR augassign2 ::= expr DUP_TOP LOAD_ATTR expr inplace_op ROT_TWO STORE_ATTR diff --git a/uncompyle6/semantics/check_ast.py b/uncompyle6/semantics/check_ast.py index 49aaedb1..67be0090 100644 --- a/uncompyle6/semantics/check_ast.py +++ b/uncompyle6/semantics/check_ast.py @@ -12,6 +12,11 @@ def checker(ast, in_loop, errors): in_loop = in_loop or ast.type in ('while1stmt', 'whileTruestmt', 'whilestmt', 'whileelsestmt', 'for_block') + if ast.type == 'augassign1' and ast[0][0] == 'and': + text = str(ast[0]) + error_text = '\n# improper augmented assigment:\n#\t' + '\n# '.join(text.split("\n")) + errors.append(error_text) + for node in ast: if not in_loop and node.type in ('continue_stmt', 'break_stmt'): text = str(node) diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index eec043dc..d32a1ae4 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -1772,7 +1772,7 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False, if deparsed.ast_errors: deparsed.write("# NOTE: have decompilation errors.\n") - deparsed.write("# Use -t option to show context of errors.") + deparsed.write("# Use -t option to show full of errors.") for err in deparsed.ast_errors: deparsed.write(err) deparsed.ERROR = True diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 98a97e4a..fcf44bd5 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -239,8 +239,12 @@ TABLE_DIRECT = { 'dict_comp_body': ( '%c:%c', 1, 0 ), 'assign': ( '%|%c = %p\n', -1, (0, 200) ), - 'augassign0': ( '%|%c = %c %c %c\n', 3, 0, 2, 1), + + # 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 ), @@ -2318,7 +2322,7 @@ def deparse_code(version, co, out=sys.stdout, showasm=None, showast=False, if deparsed.ast_errors: deparsed.write("# NOTE: have decompilation errors.\n") - deparsed.write("# Use -t option to show context of errors.") + deparsed.write("# Use -t option to full context of errors.") for err in deparsed.ast_errors: deparsed.write(err) raise SourceWalkerError("Deparsing hit an internal grammar-rule bug")