-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Update reporters to (allow) use of end_line
and end_column
#5372
Update reporters to (allow) use of end_line
and end_column
#5372
Conversation
Pull Request Test Coverage Report for Build 1499421022
💛 - Coveralls |
pylint/reporters/text.py
Outdated
for key, value in self_dict.items(): | ||
# pylint: disable=fixme | ||
# TODO: Add column to list of attributes to be printed as an empty string | ||
if value is None and key in PRINT_AS_EMPTY_STRING: | ||
self_dict[key] = "" |
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.
Is a for
- loop really necessary here? Maybe iterate only over PRINT_AS_EMPTY_STRING
and do
self_dict[key] = self_dict[key] or ""
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.
Or even better, what about this?
Initialize end_lineno
and end_col_offset
with an empty string instead ""
. You still would be able to differentiate between a null value and a number. I.e. int | Literal[""]
as type.
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.
Or even better, what about this?
Initialize
end_lineno
andend_col_offset
with an empty string instead""
. You still would be able to differentiate between a null value and a number. I.e.int | Literal[""]
as type.
I don't really like that as then we we're changing the type of end_lineno
and end_col_offset
while still "internal" to fit a specific type of reporter. For example, for the JSONReporter
it makes no sense to have it be ""
. I'm not sure if other developer have written other Reporter
but I think keeping both attributes None
until a specific reporter starts handling them is the better option here.
I'll add your first suggestion!
pylint/reporters/text.py
Outdated
# TODO: Add column to list of attributes to be printed as an empty string | ||
if value is None and key in PRINT_AS_EMPTY_STRING: | ||
self_dict[key] = "" | ||
self.writeln(self._template.format(**self_dict)) |
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.
self.writeln(msg.format(self._template))
has been quite elegant, but there is one drawback. Calling it with an unknown key raises a KeyError
. Ideally we could check a template and replace invalid values with ""
beforehand. I'm currently having the issue to implement some kind of version check in vscode-python
as calling pylint
with the new msg-template
would raise this error.
Traceback (most recent call last):
File "/.../venv-310/bin/pylint", line 33, in <module>
sys.exit(load_entry_point('pylint', 'console_scripts', 'pylint')())
File "/.../pylint/__init__.py", line 24, in run_pylint
PylintRun(sys.argv[1:])
File "/.../pylint/lint/run.py", line 398, in __init__
linter.check(args)
File "/.../pylint/lint/pylinter.py", line 992, in check
self._check_files(
File "/.../pylint/lint/pylinter.py", line 1041, in _check_files
self.add_message(symbol, args=msg)
File "/.../pylint/lint/pylinter.py", line 1513, in add_message
self._add_one_message(
File "/.../pylint/lint/pylinter.py", line 1471, in _add_one_message
self.reporter.handle_message(
File "/.../pylint/reporters/text.py", line 202, in handle_message
self.write_message(msg)
File "/.../pylint/reporters/text.py", line 192, in write_message
self.writeln(msg.format(self._template))
File "/.../pylint/message/message.py", line 94, in format
return template.format(**self._asdict())
KeyError: 'msg1'
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.
Shouldn't that just raise a new warning? Something like config-parse-error
as introduced in #5365. We could emit it on an except for the KeyError
.
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.
That doesn't really solve the issue. At the core of it its backwards incompatibility.
We should be able to use a new template, i.e. with end_lineno
, in old pylint
versions and still get a usable result. The way it's now, I need to make sure only to add end_lineno
if we are using the new pylint version.
If at some point we add another key, this will only repeat. Every time incompatible with old versions.
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.
Came up with something. A little hacky, but let me know what you think. I added if not self._checked_template:
because I thought the additional if
statement would be better than doing the regex statement each line.
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
pylint/reporters/text.py
Outdated
# TODO: Add column to list of attributes to be printed as an empty string | ||
if value is None and key in PRINT_AS_EMPTY_STRING: | ||
self_dict[key] = "" | ||
self.writeln(self._template.format(**self_dict)) |
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.
That doesn't really solve the issue. At the core of it its backwards incompatibility.
We should be able to use a new template, i.e. with end_lineno
, in old pylint
versions and still get a usable result. The way it's now, I need to make sure only to add end_lineno
if we are using the new pylint version.
If at some point we add another key, this will only repeat. Every time incompatible with old versions.
pylint/reporters/text.py
Outdated
# Check to see if all parameters in the template are attributes of the Message | ||
if not self._checked_template: | ||
template = self._template | ||
parameters = re.findall(r"\{(.+?)\}", template) | ||
for parameter in parameters: | ||
if parameter not in self_dict: | ||
template = template.replace(f"{{{parameter}}}", "") | ||
self._template = template | ||
self._checked_template = True |
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.
Can this be moved to on_set_current_module
or even __init__
? Don't now if the config settings are defined at the point already.
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.
Moved to on_set_current_module
pylint/reporters/text.py
Outdated
# Check to see if all parameters in the template are attributes of the Message | ||
if not self._checked_template: | ||
template = self._template | ||
parameters = re.findall(r"\{(.+?)\}", template) |
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.
The regex doesn't quiet work with formatting strings. Maybe something like this?
{([^:]+?)(?::([^:]+))?}
for
"{line:03d}"
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.
Used a new pattern. I think my new one works as well although the replacing is quite ugly.
pylint/reporters/text.py
Outdated
parameters = re.findall(r"\{(.+?)\}", template) | ||
for parameter in parameters: | ||
if parameter not in self_dict: | ||
template = template.replace(f"{{{parameter}}}", "") |
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.
Is it save to overwrite self._template
directly?
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.
It should be in its new place
pylint/reporters/text.py
Outdated
# Check to see if all parameters in the template are attributes of the Message | ||
template = self._template | ||
parameters = re.findall(r"\{(.+?)(:.*)?\}", template) | ||
for parameter in parameters: | ||
if parameter[0] not in Message._fields: | ||
template = re.sub(r"\{" + parameter[0] + r"(:.*?)?\}", "", template) | ||
self._template = template |
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.
Just an idea, currently this is down for every module. Can we store the original template and the new one. Then for every subsequent call, compare the "new" self._template
with the stored template
and if they match use the fixed one.
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.
It might also be a good idea to at least emit a short warning: Hey, we don't know this option are you sure?
. Otherwise we fail silently.
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.
Done and done!
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
for more information, see https://pre-commit.ci
doc/whatsnew/2.12.rst
Outdated
end of a node to the output of Pylint. If these numbers are unknown, they are represented | ||
by an empty string. | ||
|
||
* Add ``end_line`` and ``end_column`` fields to the output of the ``JSONReporter``. |
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.
It look like a breaking change that should wait for #4741. We have a 3.0 alpha branch, might be the time to dust it off ?
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.
Reverted! See #5380
Did not see change to JsonReporter
@DanielNoord I fixed the merged conflict but is this ready to review ? I'm a little lost about the order to follow between #5349 #5372 and #5336 |
#5376 was not in the 2.12.0 milestone I added 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.
LGTM ! I only have a small question.
* Add ability to add ``end_line`` and ``end_column`` to the ``--msg-template`` option. | ||
With the standard ``TextReporter`` this will add the line and column number of the | ||
end of a node to the output of Pylint. If these numbers are unknown, they are represented | ||
by an empty string. |
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 think we could also change the default for msg-template in 3.0. Do we want the default to have end line and end column ? This seems like something that is useful in an IDE but not a lot for a text output read by humans.
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.
@cdce8p Argued that we might leave the default output as is because of the potential to break many tools. I think this is a discussion which (if we want to have it anyway) we could leave until we are closer to the release of 3.0
. With this merge everybody that wants to can use this new feature!
doc/whatsnew/<current release.rst>
.Type of Changes
Description
Blocked by #5343
Ref #5336
This updates the reporters of
pylint
to start usingend_line
andend_column
. It is the first PR as mentioned in #5343 (comment)