Parsing for non-defaulted kwargs after `*args` fails
athre0z opened this issue · 3 comments
athre0z commented
import pasta
aaa = '''
def meow(self, *args, blah):
pass
'''
pasta.parse(aaa)
---------------------------------------------------------------------------
AnnotationError Traceback (most recent call last)
<ipython-input-12-cf34fed7cd55> in <module>
6 '''
7
----> 8 pasta.parse(aaa)
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/__init__.py in parse(src)
23 t = ast_utils.parse(src)
24 annotator = annotate.AstAnnotator(src)
---> 25 annotator.visit(t)
26 return t
27
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit(self, node)
1170 fmt.set(node, 'indent', self._indent)
1171 fmt.set(node, 'indent_diff', self._indent_diff)
-> 1172 super(AstAnnotator, self).visit(node)
1173 except (TypeError, ValueError, IndexError, KeyError) as e:
1174 raise AnnotationError(e)
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit(self, node)
130 def visit(self, node):
131 self._stack.append(node)
--> 132 super(BaseVisitor, self).visit(node)
133 assert node is self._stack.pop()
134
/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ast.py in visit(self, node)
260 method = 'visit_' + node.__class__.__name__
261 visitor = getattr(self, method, self.generic_visit)
--> 262 return visitor(node)
263
264 def generic_visit(self, node):
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in wrapped(self, node, *args, **kwargs)
45 if prefix:
46 self.prefix(node, default=self._indent if statement else '')
---> 47 f(self, node, *args, **kwargs)
48 if suffix:
49 self.suffix(node, max_lines=max_suffix_lines, semicolon=semicolon,
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit_Module(self, node)
218 @module
219 def visit_Module(self, node):
--> 220 self.generic_visit(node)
221
222 @block_statement
/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ast.py in generic_visit(self, node)
268 for item in value:
269 if isinstance(item, AST):
--> 270 self.visit(item)
271 elif isinstance(value, AST):
272 self.visit(value)
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit(self, node)
1170 fmt.set(node, 'indent', self._indent)
1171 fmt.set(node, 'indent_diff', self._indent_diff)
-> 1172 super(AstAnnotator, self).visit(node)
1173 except (TypeError, ValueError, IndexError, KeyError) as e:
1174 raise AnnotationError(e)
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit(self, node)
130 def visit(self, node):
131 self._stack.append(node)
--> 132 super(BaseVisitor, self).visit(node)
133 assert node is self._stack.pop()
134
/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ast.py in visit(self, node)
260 method = 'visit_' + node.__class__.__name__
261 visitor = getattr(self, method, self.generic_visit)
--> 262 return visitor(node)
263
264 def generic_visit(self, node):
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in wrapped(self, node, *args, **kwargs)
93 def wrapped(self, node, *args, **kwargs):
94 self.prefix(node, default=self._indent)
---> 95 f(self, node, *args, **kwargs)
96 if hasattr(self, 'block_suffix'):
97 last_child = ast_utils.get_last_child(node)
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit_FunctionDef(self, node)
399 with self.scope(node, 'args', trailing_comma=args_count > 0,
400 default_parens=True):
--> 401 self.visit(node.args)
402
403 if getattr(node, 'returns', None):
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit(self, node)
1170 fmt.set(node, 'indent', self._indent)
1171 fmt.set(node, 'indent_diff', self._indent_diff)
-> 1172 super(AstAnnotator, self).visit(node)
1173 except (TypeError, ValueError, IndexError, KeyError) as e:
1174 raise AnnotationError(e)
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit(self, node)
130 def visit(self, node):
131 self._stack.append(node)
--> 132 super(BaseVisitor, self).visit(node)
133 assert node is self._stack.pop()
134
/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ast.py in visit(self, node)
260 method = 'visit_' + node.__class__.__name__
261 visitor = getattr(self, method, self.generic_visit)
--> 262 return visitor(node)
263
264 def generic_visit(self, node):
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in wrapped(self, node, *args, **kwargs)
45 if prefix:
46 self.prefix(node, default=self._indent if statement else '')
---> 47 f(self, node, *args, **kwargs)
48 if suffix:
49 self.suffix(node, max_lines=max_suffix_lines, semicolon=semicolon,
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in visit_arguments(self, node)
1083 self.visit(arg)
1084 self.attr(node, 'kw_default_%d' % i, [self.ws, '=', self.ws],
-> 1085 default='=')
1086 self.visit(default)
1087 arg_i += 1
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in attr(***failed resolving arguments***)
1387 for attr_val in attr_vals:
1388 if isinstance(attr_val, six.string_types):
-> 1389 attr_parts.append(self.token(attr_val))
1390 else:
1391 attr_parts.append(attr_val())
/private/tmp/test2/venv/lib/python3.7/site-packages/pasta/base/annotate.py in token(self, token_val)
1313 if token.src != token_val:
1314 raise AnnotationError("Expected %r but found %r\nline %d: %s" % (
-> 1315 token_val, token.src, token.start[0], token.line))
1316
1317 # If the token opens or closes a parentheses scope, keep track of it
AnnotationError: Expected '=' but found ')'
line 2: def meow(self, *args, blah):
This is valid syntax in Python 3. IIRC, this wasn't always the case but later added in a 3.X version, although I'm not exactly sure when.
soupytwist commented
Indeed this fails on at least 3.4+. Thanks for reporting!
athre0z commented
Reported and fixed within 10 minutes. That's one hell of a turn-around time! Thanks!
soupytwist commented
Your detailed bug report made it very easy :)
Thank you!