Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Update pylint msg-template to show human-friendly error symbols. #495

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

Closed
wants to merge 5 commits into from

Conversation

jcdyer
Copy link

@jcdyer jcdyer commented Dec 29, 2017

New msg-template adds ({symbol}), and updates pylintArgs description to explain that overriding --msg-template can't be done.

Fixes #382.

@msftclas
Copy link

msftclas commented Dec 29, 2017

CLA assistant check
All CLA requirements met.

@AWPelican
Copy link

AWPelican commented Jan 1, 2018

Question here: do we think it's important to leave the original msg_id in the message? It seems redundant to have both since they both serve the same purpose.

I would almost suggest something like this:

{msg} ({symbol})

instead of

{msg_id}:{msg} ({symbol})

Unless we think it's still necessary to have the msg_id present in the message for some reason?

@jcdyer
Copy link
Author

jcdyer commented Jan 1, 2018

While I do think the numeric codes are redundant, people who use VSCode will have built up workflows around the information that was available to them, and it might be disruptive to remove that information. Specifically, I'm thinking that people will have used the numeric codes in their local # pylint: disable=Xnnn directives, and will have a harder time maintaining stylistic consistency in future disables, if the information isn't still presented to them in the linting messages.

Additionally, I could add a new setting to allow users to customize the non-essential part of the message template. So the new template would be '{line},{column},{category},%s' % (message,) where message defaults to {msg} ({symbol}), but can be overridden in python.linting.pylintMessageFormat. The setting would have a help string like:

Controls the message template for linting results, as a new-style python format
string. The provided value will be appended to '{line},{column},{category},',
which is required by VSCode. The previous message format, using numeric message
codes, can be restored by setting this to '{msg_id}:{msg}'.  Available fields are
described at https://pylint.readthedocs.io/en/latest/user_guide/output.html.

@AWPelican
Copy link

Yes, you're right. It's a great point and I agree. It's important to respect existing workflows.

Your suggestion seems like an elegant solution to me, as it allows one to take advantage of the rich options for message control that Pylint offers.

@jcdyer jcdyer force-pushed the pylint-template-update branch from dbb17c0 to d35e8dc Compare January 2, 2018 16:27
@brettcannon
Copy link
Member

brettcannon commented Jan 3, 2018

Two things, @jcdyer . One, thanks for the PR! Most of us just got back from vacation, but we will get to reviewing your PR at some point.

Two, Travis is failing on this PR, so if you could fix that it would be great.

And thanks for providing feedback, @AWPelican , on the PR. In the end @jcdyer said what I would have as to why we need to keep the message IDs. 😄 Although I would be open to changing the format to {symbol}: {msg} ({msg_id}) to emphasize the human-friendly message.

@DonJayamanne
Copy link

@jcdyer @brettcannon
I believe we should retain the current format as Brett has suggested. The change you have made removes the msg_id but provides instructions in the config file. My preference is to make the changes backwards compatible.

The CI tests are failling over as the msg_id is missing.
Also, if you are going to make the format configurable, then you'll need to alter the regular expression used to parse the output. The default (named groups) regular expression is as follows (code is what maps to msg_id):

const REGEX = '(?<line>\\d+),(?<column>\\d+),(?<type>\\w+),(?<code>\\w\\d+):(?<message>.*)\\r?(\\n|$)';

package.json Outdated
"python.linting.pylintMsgTemplate": {
"type": "string",
"description": "Controls the message template for linting results, as a new-style python format string. The provided value will be appended to '{line},{column},{category},', which is required by VSCode. The previous message format, using numeric message codes, can be restored by setting this to '{msg_id}:{msg}'. Available fields are described at https://pylint.readthedocs.io/en/latest/user_guide/output.html.",
"default": "{msg} ({symbol})",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcdyer My preference is to make the changes backwards compatible. You'll need to include msg_id

@@ -11,7 +11,8 @@ export class Linter extends baseLinter.BaseLinter {
}

protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise<baseLinter.ILintMessage[]> {
const messages = await this.run(['--msg-template=\'{line},{column},{category},{msg_id}:{msg}\'', '--reports=n', '--output-format=text', document.uri.fsPath], document, cancellation);
const msgTemplate = `'{line},{column},{category},${this.pythonSettings.linting.pylintMsgTemplate}'`;
const messages = await this.run([`--msg-template=${msgTemplate}`, '--reports=n', '--output-format=text', document.uri.fsPath], document, cancellation);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI tests are failling over as the msg_id is missing.
Also, if you are going to make the format configurable, then you'll need to alter the regular expression used to parse the output. The default (named groups) regular expression is as follows (code is what maps to msg_id):

const REGEX = '(?<line>\\d+),(?<column>\\d+),(?<type>\\w+),(?<code>\\w\\d+):(?<message>.*)\\r?(\\n|$)';

The regex is the last paramter passed into the run method (here isn't not passed as we're using the default regex)

Copy link
Author

@jcdyer jcdyer Jan 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. Thank you. I see that "code" gets passed through to VSCode in the diagnostic at lintProviders.ts#L38. It seems like it would be too complex to ask a user to provide a custom msg-template AND a regular expression to match the provided template and extract the relevant code.

Two possible solutions I see:

  1. Automatically generate the regular expression based on the template the user provides, If {symbol} is included, use that as the code, otherwise if {code} is included, use that. If neither is included, add the code outside the visible message, and return that.
  2. Provided an enumerated configuration option for message templates:
    • Legacy:

      msgTemplate = '{msg_id}:{msg}';
      regEx =  '(?<line>\\d+),(?<column>\\d+),(?<type>\\w+),(?<code>\\w\\d+):(?<message>.*)\\r?(\\n|$)';
      
    • Standard:

      msgTemplate = '{msg} ({symbol})';
      regEx = '^(?<line>\\d+),(?<column>\\d+),(?<type>\\w+),(?<message>.*) \((?<code>[\w-]+)\)$';
      

(Regex to be validated).

I'd feel pretty comfortable calling the one with the symbolic name "standard", as a quick test suggests that pylint hasn't included the numeric code in the default output since before v1.0.

Copy link
Author

@jcdyer jcdyer Jan 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the formatting. I'll try to clean it up. I'm leaning toward number 2 as it's simpler, and solves the problem at hand. The one complication I see is that lintProviders#L37 assumes that the message should be displayed as {code}:{message}, which is not the PyLint standard, but that's not an insurmountable problem.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I too prefer option 2

@jcdyer
Copy link
Author

jcdyer commented Jan 5, 2018

I'll have time to fix this up this weekend.

@jcdyer
Copy link
Author

jcdyer commented Jan 10, 2018

This is not ready for another review yet. I'll get it cleaned up soon.

Allow creating diagnostics with pre-formatted message strings.
@jcdyer jcdyer force-pushed the pylint-template-update branch from a8b70de to 656c3d8 Compare January 10, 2018 03:39
@codecov
Copy link

codecov bot commented Jan 10, 2018

Codecov Report

Merging #495 into master will increase coverage by 0.09%.
The diff coverage is 95.23%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #495      +/-   ##
==========================================
+ Coverage   56.29%   56.38%   +0.09%     
==========================================
  Files         212      212              
  Lines        9975     9993      +18     
  Branches     1754     1759       +5     
==========================================
+ Hits         5615     5635      +20     
+ Misses       4355     4353       -2     
  Partials        5        5
Impacted Files Coverage Δ
src/client/common/configSettings.ts 91.39% <ø> (ø) ⬆️
src/client/linters/prospector.ts 26.31% <ø> (ø) ⬆️
src/client/linters/baseLinter.ts 92.23% <100%> (ø) ⬆️
src/client/linters/pylint.ts 100% <100%> (ø) ⬆️
src/client/common/constants.ts 100% <100%> (ø) ⬆️
src/client/providers/lintProvider.ts 82.8% <83.33%> (-0.1%) ⬇️
src/client/providers/jediProxy.ts 72.5% <0%> (+0.5%) ⬆️
src/client/providers/definitionProvider.ts 89.28% <0%> (+3.57%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d421dd3...c140167. Read the comment docs.

@jcdyer jcdyer force-pushed the pylint-template-update branch from 974b5d3 to c4917fb Compare January 10, 2018 16:02
@jcdyer
Copy link
Author

jcdyer commented Jan 10, 2018

Some questions and concerns:

  • Should I update the type of pylintMsgTemplate from string to 'legacy' | 'standard'? And should I create a named type for that?

  • I don't think src/test/linters/lint.test.ts:testLinterMessages actually looks at the format of the messages. It only seems to check that messages exist when they should, and don't exist when they shouldn't. As it stands, the big lists of ILintingMessage objects in that file could be replaced by booleans: pylintHasMessages: true. But I tried to make my message objects accurate in case someone decides to flesh out those tests.

  • There are some multi-line error messages (bad-whitespace, for instance), which cause the symbolic code at the end not to be displayed, because the error messages are truncated after the first line. The authors of pylint moved the error message to the end, and in parentheses, probably because the symbolic codes were harder to visually parse out than the numeric codes, but perhaps it would look reasonable to have it in parentheses before the message. Compare:

    bad-whitespace:Exactly one space required after comma
    (bad-whitespace) Exactly one space required after comma
    

    Vs. the current version with no code:

    Exactly one space required after comma
    

Another option would be to show the full multi-line message, but I'm not sure whether this is desirable, or where to enable it. I think other languages (like Rust) do it, but they have more verbose error messages in general.

@brettcannon
Copy link
Member

@DonJayamanne any answers for the questions from @jcdyer ?

@DonJayamanne
Copy link

Should I update the type of pylintMsgTemplate from string to 'legacy' | 'standard'? And should I

create a named type for that?

Named type would be the way to go.

(bad-whitespace) Exactly one space required after comma

Agreed with this format, Thought I'd still prefer to see the msg_id suffixed at the end of the above message.

@brettcannon Based on the PR, the new display format would not include the msg_id in the problems window. Would that be an issue. Personally I'd prefer to see that, legacy or not, as I'd like to be able to exclude the error from the pylint config.

@brettcannon @jcdyer
Finally, shouldn't we be consistent in the way error messages are formatted for each linter. Irrespective of the linter, we should have a specific format for the messages displayed:
Either <code>:<message> or <message> (<code>) or similar.

Have a look at the following messages below:
screen shot 2018-01-16 at 2 28 59 pm

@brettcannon
Copy link
Member

Leaving the ID in is fine by me (some people will want that info), and I agree we should be consistent in the formatting for our own sanity in the code. 😉 I say put the user-readable name first, then the message ID since the human-readable part is what most people will use.

@jcdyer
Copy link
Author

jcdyer commented Jan 31, 2018

@DonJayamanne @brettcannon: I'm going to have some time to look at this again soon.

Personally I'd prefer to see that, legacy or not, as I'd like to be able to exclude the error from the pylint config.

You can (and should) use the textual version for excluded lints. # pylint: exclude=unused-import works just as well as # pylint: exclude=W0611, and is better documentation.

That said, the consensus seems to be to include both of them, so I'll do that.

@AWPelican
Copy link

AWPelican commented Jan 31, 2018 via email

@DonJayamanne
Copy link

@jcdyer Thanks for taking the time to address our comments.

@brettcannon
Copy link
Member

@jcdyer We're hitting code freeze today, so this won't' make it in this release. Will you have time do you think to fix the merge conflicts and add back in the error number request that @DonJayamanne made for the next release?

@jcdyer
Copy link
Author

jcdyer commented Mar 5, 2018

Yes. I should have time later this week. Sorry this slipped off my radar.

@brettcannon
Copy link
Member

@jcdyer No problem! This PR just came up in a team meeting and so I wanted to help move it forward.

@joshburkart
Copy link

This would be a great feature to get in! I currently run pylint --help-msg=W... all the time to figure out the human-readable message to disable... :P

@brettcannon
Copy link
Member

If @jcdyer can't get an update, did you want to fork the PR and update it so we can merge it, @joshburkart ?

@joshburkart
Copy link

@brettcannon @jcdyer I'd love to! But unfortunately I think this PR looks a bit too complicated/involved for me to feel comfortable diving in, at the moment... :(

@brettcannon
Copy link
Member

@joshburkart np

@brettcannon
Copy link
Member

I'm going to close this issue since it isn't currently going anywhere. If anyone finds the time to fix the conflicts and address Don's comments then we can open this back up, otherwise we will try to fix it for the May release.

@brettcannon brettcannon closed this Apr 9, 2018
@joshburkart
Copy link

joshburkart commented Jul 23, 2018

Ping @jcdyer?

@RasmusWL
Copy link

Hi @brettcannon. I was missing the {symbol} in the output of this extension, and was looking into making a PR for fixing this.

I read through the discussion here, and have a suggestion to solve the issue without being too disruptive:

Use {msg_id}({symbol}): {msg} as the format. This is pretty much what the Parseable predefined format from pylint outputs. Messages will look like:

C0326(bad-whitespace): No space allowed around bracket

Maybe I'm suffering from Stockholm's syndrome after reading these in Jenkins output whenever my PR's contain pylint problems, but I think it is very nicely readable. It keeps the numbers, but also presents the human readable {symbol} clearly.

A detail I didn't see mentioned here is that in {msg_id}, the first letter shows what kind of problem we're dealing with; in this case a C means it is a convention.

Let me know if this could be an acceptable fix, and I will implement it (in a new PR from scratch) 😊


From the pylint tutorial:

  * (C) convention, for programming standard violation
  * (R) refactor, for bad code smell
  * (W) warning, for python specific problems
  * (E) error, for much probably bugs in the code
  * (F) fatal, if an error occurred which prevented pylint from doing further processing.

@joshclimacell
Copy link

FWIW I switched to using prospector for linting Python in VSCode, which itself runs pylint and reports the human-readable pylint codes.

@brettcannon
Copy link
Member

@qubitron do you have any input?

@ta32
Copy link

ta32 commented Jan 30, 2019

@jcdyer I can no longer see the numeric code for the warnings is this normal?

@DonJayamanne
Copy link

Yes

@EriKWDev
Copy link

@jcdyer, @joshclimacell, @brettcannon
In what release do you expect these changes to take place?
I would love to see the old {msg_id} in the warning messages since our workflow at my workplace requires us to use:

# <reason for pylint-disable> pylint: disable=<numerical error representation>

@brettcannon
Copy link
Member

@EriKWDev the PR was closed without merging, so there are no plans. If you would like the message changed then please open a new feature request.

@microsoft microsoft locked as resolved and limited conversation to collaborators Jul 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pylint message template overridden by linter
10 participants