diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 32402864..7e122fef 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -636,6 +636,27 @@ class Python3Parser(PythonParser): rule = ('mkfunc ::= kwargs %sexpr %s' % ('pos_arg ' * args_pos, opname)) self.add_unique_rule(rule, opname, token.attr, customize) + if opname.startswith('MAKE_FUNCTION_A'): + # rule = ('mkfunc2 ::= %s%sEXTENDED_ARG %s' % + # ('pos_arg ' * (args_pos), 'kwargs ' * (annotate_args-1), opname)) + self.add_unique_rule(rule, opname, token.attr, customize) + if self.version >= 3.3: + rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST LOAD_CONST EXTENDED_ARG %s' % + (('pos_arg ' * (args_pos)), + ('call_function ' * (annotate_args-1)), opname)) + self.add_unique_rule(rule, opname, token.attr, customize) + rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST LOAD_CONST EXTENDED_ARG %s' % + (('pos_arg ' * (args_pos)), + ('annotate_arg ' * (annotate_args-1)), opname)) + else: + rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST EXTENDED_ARG %s' % + (('pos_arg ' * (args_pos)), + ('annotate_arg ' * (annotate_args-1)), opname)) + self.add_unique_rule(rule, opname, token.attr, customize) + rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST EXTENDED_ARG %s' % + (('pos_arg ' * (args_pos)), + ('call_function ' * (annotate_args-1)), opname)) + self.add_unique_rule(rule, opname, token.attr, customize) elif opname_base == 'CALL_METHOD': # PyPy only - DRY with parse2 @@ -696,6 +717,8 @@ class Python3Parser(PythonParser): self.check_reduce['augassign1'] = 'AST' self.check_reduce['augassign2'] = 'AST' self.check_reduce['while1stmt'] = 'noAST' + self.check_reduce['annotate_tuple'] = 'noAST' + self.check_reduce['kwarg'] = 'noAST' # FIXME: remove parser errors caused by the below # self.check_reduce['while1elsestmt'] = 'noAST' return @@ -704,6 +727,10 @@ class Python3Parser(PythonParser): lhs = rule[0] if lhs in ('augassign1', 'augassign2') and ast[0][0] == 'and': return True + elif lhs == 'annotate_tuple': + return not isinstance(tokens[first].attr, tuple) + elif lhs == 'kwarg': + return not isinstance(tokens[first].attr, str) elif lhs == 'while1elsestmt': # if SETUP_LOOP target spans the else part, then this is # not while1else. Also do for whileTrue? diff --git a/uncompyle6/parsers/parse31.py b/uncompyle6/parsers/parse31.py index 647ed421..bda76fa8 100644 --- a/uncompyle6/parsers/parse31.py +++ b/uncompyle6/parsers/parse31.py @@ -36,16 +36,8 @@ class Python31Parser(Python32Parser): def add_custom_rules(self, tokens, customize): super(Python31Parser, self).add_custom_rules(tokens, customize) - for i, token in enumerate(tokens): - opname = token.type - if opname.startswith('MAKE_FUNCTION_A'): - args_pos, args_kw, annotate_args = token.attr - # Check that there are 2 annotated params? - # rule = ('mkfunc2 ::= %s%sEXTENDED_ARG %s' % - # ('pos_arg ' * (args_pos), 'kwargs ' * (annotate_args-1), opname)) - rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST EXTENDED_ARG %s' % - (('pos_arg ' * (args_pos)), - ('annotate_arg ' * (annotate_args-1)), opname)) - self.add_unique_rule(rule, opname, token.attr, customize) + return + pass + class Python31ParserSingle(Python31Parser, PythonParserSingle): pass diff --git a/uncompyle6/parsers/parse32.py b/uncompyle6/parsers/parse32.py index cac33810..b9610664 100644 --- a/uncompyle6/parsers/parse32.py +++ b/uncompyle6/parsers/parse32.py @@ -46,6 +46,9 @@ class Python32Parser(Python3Parser): (('pos_arg ' * (args_pos)), ('annotate_arg ' * (annotate_args-1)), opname)) self.add_unique_rule(rule, opname, token.attr, customize) + pass + return + pass class Python32ParserSingle(Python32Parser, PythonParserSingle): diff --git a/uncompyle6/semantics/make_function.py b/uncompyle6/semantics/make_function.py index 23fa62d0..c22050d2 100644 --- a/uncompyle6/semantics/make_function.py +++ b/uncompyle6/semantics/make_function.py @@ -148,12 +148,15 @@ def make_function3_annotate(self, node, isLambda, nested=1, suffix = '' for param in paramnames[:i]: self.write(suffix, param) - if param in annotate_args: - value, string = annotate_args[param] - if string: - self.write(': "%s"' % value) - else: - self.write(': %s' % value) + if param in annotate_tuple[0].attr: + p = annotate_tuple[0].attr.index(param) + self.write(': ') + self.preorder(node[p]) + # value, string = annotate_args[param] + # if string: + # self.write(': "%s"' % value) + # else: + # self.write(': %s' % value) suffix = ', ' suffix = ', ' if i > 0 else '' @@ -210,12 +213,14 @@ def make_function3_annotate(self, node, isLambda, nested=1, self.write(": ") else: self.write(')') - if 'return' in annotate_args: - value, string = annotate_args['return'] - if string: - self.write(' -> "%s"' % value) - else: - self.write(' -> %s' % value) + if 'return' in annotate_tuple[0].attr: + self.write(' -> ') + # value, string = annotate_args['return'] + # if string: + # self.write(' -> "%s"' % value) + # else: + # self.write(' -> %s' % value) + self.preorder(node[annotate_last-1]) self.println(":") diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 8b49eace..44482879 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -624,7 +624,9 @@ class SourceWalker(GenericASTTraversal, object): code = node[-3] self.indentMore() - annotate_last = -4 if self.version == 3.1 else -5 + for annotate_last in range(len(node)-1, -1, -1): + if node[annotate_last] == 'annotate_tuple': + break # FIXME: handle and pass full annotate args make_function3_annotate(self, node, isLambda=False,