-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
error reporting includes columns #2163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8efc46d
3eb173f
e8f9edb
de8589d
3811846
d733c7e
8457e7a
ec3b91d
2c3391c
fb1205a
e580367
94d8079
1603b44
7c17e92
99a0496
77e7399
75bd4a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,7 +70,7 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None, | |
except (SyntaxError, TypeCommentParseError) as e: | ||
if errors: | ||
errors.set_file('<input>' if fnam is None else fnam) | ||
errors.report(e.lineno, e.msg) | ||
errors.report(e.lineno, e.offset, e.msg) | ||
else: | ||
raise | ||
|
||
|
@@ -84,8 +84,8 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None, | |
def parse_type_comment(type_comment: str, line: int) -> Type: | ||
try: | ||
typ = ast35.parse(type_comment, '<type_comment>', 'eval') | ||
except SyntaxError: | ||
raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, line) | ||
except SyntaxError as e: | ||
raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, line, e.offset) | ||
else: | ||
assert isinstance(typ, ast35.Expression) | ||
return TypeConverter(line=line).visit(typ.body) | ||
|
@@ -95,7 +95,7 @@ def with_line(f: Callable[['ASTConverter', T], U]) -> Callable[['ASTConverter', | |
@wraps(f) | ||
def wrapper(self: 'ASTConverter', ast: T) -> U: | ||
node = f(self, ast) | ||
node.set_line(ast.lineno) | ||
node.set_line(ast.lineno, ast.col_offset) | ||
return node | ||
return wrapper | ||
|
||
|
@@ -260,7 +260,7 @@ def do_func_def(self, n: Union[ast35.FunctionDef, ast35.AsyncFunctionDef], | |
try: | ||
func_type_ast = ast35.parse(n.type_comment, '<func_type>', 'func_type') | ||
except SyntaxError: | ||
raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, n.lineno) | ||
raise TypeCommentParseError(TYPE_COMMENT_SYNTAX_ERROR, n.lineno, n.col_offset) | ||
assert isinstance(func_type_ast, ast35.FunctionType) | ||
# for ellipsis arg | ||
if (len(func_type_ast.argtypes) == 1 and | ||
|
@@ -600,6 +600,7 @@ def visit_UnaryOp(self, n: ast35.UnaryOp) -> Node: | |
def visit_Lambda(self, n: ast35.Lambda) -> Node: | ||
body = ast35.Return(n.body) | ||
body.lineno = n.lineno | ||
body.col_offset = n.col_offset | ||
|
||
return FuncExpr(self.transform_args(n.args, n.lineno), | ||
self.as_block([body], n.lineno)) | ||
|
@@ -804,7 +805,8 @@ def visit_raw_str(self, s: str) -> Type: | |
return parse_type_comment(s.strip(), line=self.line) | ||
|
||
def generic_visit(self, node: ast35.AST) -> None: | ||
raise TypeCommentParseError(TYPE_COMMENT_AST_ERROR, self.line) | ||
raise TypeCommentParseError(TYPE_COMMENT_AST_ERROR, self.line, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unfortunately I think we still need the getattr here... not all AST nodes come with column info, only the ones deriving from stmt, expr, etc... (https://github.com/python/typeshed/blob/master/third_party/3/typed_ast/ast35.pyi) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's fine! |
||
getattr(node, 'col_offset', -1)) | ||
|
||
def visit_NoneType(self, n: Any) -> Type: | ||
return None | ||
|
@@ -860,6 +862,7 @@ def visit_List(self, n: ast35.List) -> Type: | |
|
||
|
||
class TypeCommentParseError(Exception): | ||
def __init__(self, msg: str, lineno: int) -> None: | ||
def __init__(self, msg: str, lineno: int, offset: int) -> None: | ||
self.msg = msg | ||
self.lineno = lineno | ||
self.offset = offset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't the 0th and first elements need to be compared too?
also, is ignoring the column necessary b/c of the TODO in
TypeConverter#generic_visit
infastparse.py
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they're taken care of because we're within the while loop.
Ignoring the column here, so that we only get the first instance of this particular error within the line. This logic could be tweaked, for sure. Maybe we actually do want to expose all instances of a given error. E.g.