-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Add end_lineno
and end_col_offset
to nodes
#1258
Conversation
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.
Looks great, I only have two minor remarks.
astroid/rebuilder.py
Outdated
@@ -1607,7 +1607,7 @@ def visit_attribute( | |||
if not isinstance(parent, nodes.ExceptHandler): | |||
self._delayed_assattr.append(newnode) | |||
else: | |||
if sys.version_info >= (3, 8): | |||
if sys.version_info >= (3, 8): # pylint: disable=else-if-used |
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.
As discussed in the other issue, I don't think it's a false positive.
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.
Even if not a false-positive, I would recommend to keep the pylint: disable
as this preserves the symmetry with all other cases and will make removing the check once 3.8
is the default much easier.
@@ -1134,18 +1257,37 @@ def visit_decorators( | |||
return None | |||
# /!\ node is actually an _ast.FunctionDef node while | |||
# parent is an astroid.nodes.FunctionDef node | |||
if PY38_PLUS: | |||
if sys.version_info >= (3, 8): |
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.
Huhu. I'm going to stop suggesting for every test then. But why though ? I'd say it's a good thing to use PY38+ if only for the performance increase of not having to recalculate the bool everytime ?
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.
True, I don't really like the performance impact either. On the positive side sys.version_info
is special cased by type checkers so they know how to infer it. That doesn't work with PY38_PLUS
.
If performance is a real concern, the only other option, I think, would be to conditional define the visit_xxx
methods itself. That would mean a lot of code duplications though. Not sure we could maintain that, at least not easily.
In the end, it's only the node tree. So the performance impact might be acceptable.
--
if sys.version_info >= (3, 8):
def visit_constant(self, node: "ast.Constant", parent: NodeNG) -> nodes.Const:
"""visit a Constant node by returning a fresh instance of Const"""
return nodes.Const(
value=node.value,
kind=node.kind,
lineno=node.lineno,
col_offset=node.col_offset,
end_lineno=node.end_lineno,
end_col_offset=node.end_col_offset,
parent=parent,
)
else:
def visit_constant(self, node: "ast.Constant", parent: NodeNG) -> nodes.Const:
"""visit a Constant node by returning a fresh instance of Const"""
return nodes.Const(
node.value,
node.lineno,
node.col_offset,
parent,
node.kind,
)
Based on the documentation of (A similar point can be made for |
If I understand you correctly, what you would like is for IntelliSense to know that some nodes will always have class Module(LocalsDictNodeNG):
lineno: None
col_offset: None
end_lineno: None
end_col_offset: None
parent: None |
Ah I didn't know not all |
63fa73a
to
309da22
Compare
Actually, no node subclasses |
Took a moment to get this ready, especially writing the tests. I believe it's now ready for review. Some additional comments regarding things I noticed while working on it:
|
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.
Amazing work ! Do you want to wait for 2.9.0 ? Should we use astroid 2.9.0 in pylint 2.12 ? We could bump the other 2.9.0 features in 2.10 so we can release the end column/end line.
assert (c1.keywords[0].lineno, c1.keywords[0].col_offset) == (3, 16) | ||
assert (c1.keywords[0].end_lineno, c1.keywords[0].end_col_offset) == (3, 22) | ||
assert (c1.body[0].lineno, c1.body[0].col_offset) == (4, 4) | ||
assert (c1.body[0].end_lineno, c1.body[0].end_col_offset) == (4, 8) |
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.
I just reviewed the content of the test, not the expected column. But it comes from the ast, if it's wrong there isn't a lot we can do, right ?
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.
True, at least not without significant effort. One area I was able to fix fairly easily was Arguments
. See the snipped below. We might also be able to address the AssignName
issue I mentioned by parsing the source code ourselves but that is definitely an issue for another time.
Usually the worse that can happen is that the lineno and col_offset also include the parent node. This is still correct just not as accurate as we would like it to be for error highlighting.
The true value of these tests is to know when a new version changed something. Like knowing that Keywords
and Slice
only include end_lineno
in 3.9, or the issue with Arguments
.
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.
Great work @cdce8p! Writing those tests must not have been an easy task.
I would consider this a new feature that probably deserves its own minor version. I.e. release |
Sounds good, do we still release 2.8.6 first ? |
Could make sense if it isn't too much effort. What is your opinion? |
Hmm, I forgot to deprecate python 3.6.0 and 3.6.1. I'm going release 2.8.7 with the deprecation and suggest astroid 2.6.6 (as it's the one working with pylint 2.9.3). |
* Add end_lineno and end_col_offset infomation * Add annotations for fields that are always None * Changelog entry Requires Python 3.8
* Add end_lineno and end_col_offset infomation * Add annotations for fields that are always None * Changelog entry Requires Python 3.8
Description
In Python 3.8,
end_lineno
andend_col_offset
where added to all AST nodes which already hadlineno
andcol_offset
information. This PR adds them to the astoid nodes. Part of pylint-dev/pylint#5336Type of Changes
Todo list
end_lineno
,end_col_offset
sys.version_info >= (3, 8)
checks are ok, or ifgetattr(node, 'end_lineno', None)
should be used.Note:
getattr
can't be checked withmypy
.TODOs
in code