Fix some errors in deparsing Python 3 annotations

This commit is contained in:
rocky
2017-01-07 03:03:53 -05:00
parent 7b8c5e091c
commit 99fce6dfd7
5 changed files with 53 additions and 24 deletions

View File

@@ -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?

View File

@@ -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

View File

@@ -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):

View File

@@ -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(":")

View File

@@ -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,