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 comparison-of-constants
checker
#6413
Conversation
There are so many stupid commits saying "Merge branch 'PyCQA:main' into main". Does github automagically squash these away when/if the branch eventually gets merged? |
I notice that my check only fires once for lines like |
Pull Request Test Coverage Report for Build 2272482650
π - Coveralls |
Well yes, we can squash all the commit when we merge. But you can also rebase on the latest |
The remaining failing tests appear to be because of this kind of thing:
In particular, I'm concerned about |
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 this need some functional tests, this could be by removing disable in existing "comparison" functional files, but creating a new file would be nice too.
tests/functional/ext/comparison_placement/misplaced_comparison_constant.py
Outdated
Show resolved
Hide resolved
The test failing right now needs to add the expected result in functional py file with |
My opinion is it's covered by a3f3e61, what do you think? Is there something missing? |
It would be good to have a separate file as well. That makes it easy to see what a message is testing by quickly looking up the message name in the test directory. We will also need some documentation as discussed in #5953. |
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 good already, it's a very nice first step toward catching all constant comparison !
As for commit 864c1c1. The tests are failing because the literal-comparison lint is no longer firing on certain lines in |
Can anyone here see why "Checks / documentation" has failed? |
@omarandlorraine the bad.py file in the documentation does not raise |
Was there any thought given to reusing |
No, I wasn't even aware of it. |
Okay, the tests have passed, and I think it is ready to be merged in. Do you agree? |
I'm sorry @omarandlorraine I did not remember that we already had a very close warnings for that kind of problem. Thank you Jacob for noticing. I think creating a new message makes sense because the old one is a constant as in |
I was just wondering, but now after thinking a bit, I take it back. I see now that |
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.
Looking good. Sorry for the message change, it will require an upgrade of the result of the functional tests. Let's hear about what other think of it before changing it again. This is user facing, the clearer it is the better.
Generally in the changelog you should keep both entry (inserting your own changelog randomly help, as conflicts happens a lot more for the first entry and last entry). Regarding the other conflict it's easier to resolve with a global vision of the other MR so I did it :) The change came from #6492 |
Generally to avoid the problem you could use |
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 code itself looks good,great even, thank you for your contribution @omarandlorraine.
Regarding the message description and name and its consistency with other pylint message, I think there's two possible solutions:
- We suppress comparison-of-constants if a less generic one would be raised π
- We raise two messages, after all one fix will remove both... π
I think suppression message in some context would bring complexity. What happens if the less generic message is disabled for example, should we still suppress comparison-of-constants ?
Let me know what you think of the two options and if something else could be done, then I think we should vote on the best solution to merge this before yet another change in main create a conflict π
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.
Thanks for fixing the merge @omarandlorraine!
Sorry if my comments seem a bit much, that sort of thing happens naturally with larger PRs like these. (152 lines is quite a lot for our project).
To explain two seemingly nitpicky recurring comments:
- Adding disables at the top of the file is helpful for later contributors as they don't need to add in-line disables for the same problem. Besides, they tend to keep the testable code clean.
- Adding double spaces between comments and codes helps contributors who have set up their IDE to auto-format on save. My IDE auto-formats 95% of the code to this project's style. Normally such deviations would be caught by
pre-commit
, but some of the test files are excluded. However, when I (or somebody else) ever revisits these tests they won't be able to easily save without reformatting the complete file. Sticking to the project's style in tests even withoutpre-commit
is therefore useful for many contributors/reviewers and increases their productivity. It's a bit nitpicky now, but would be much appreciated π
@@ -58,6 +59,13 @@ class ComparisonChecker(_BasicChecker): | |||
"comparison-with-itself", | |||
"Used when something is compared against itself.", | |||
), | |||
"R0125": ( | |||
"Comparison between constants: '%s %s %s' is also a constant, remove the comparison and consider a refactor", |
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.
"Comparison between constants: '%s %s %s' is also a constant, remove the comparison and consider a refactor", | |
"Comparison between constants: '%s %s %s' has a constant value", |
The R
in R0125
implies that the code should be refactored so I think we can leave that out of the message here.
"When two literals are compared with each other the result is a constant, " | ||
"and using the constant directly is both easier to read and more performant." | ||
" Initializing 'True' and 'False' this way is not required since python 2.3", |
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.
"When two literals are compared with each other the result is a constant, " | |
"and using the constant directly is both easier to read and more performant." | |
" Initializing 'True' and 'False' this way is not required since python 2.3", | |
"When two literals are compared with each other the result is a constant. " | |
"Using the constant directly is both easier to read and more performant. " | |
"Initializing 'True' and 'False' this way is not required since Python 2.3.", |
@@ -11,21 +11,21 @@ def foo(): | |||
return True | |||
elif arg <= arg: # [comparison-with-itself] | |||
return True | |||
elif None == None: # [comparison-with-itself] | |||
elif None == None: # [comparison-of-constants, comparison-with-itself] |
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 we're updating these comments as well, could you add the double spaces here?
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'll try using the autoformatter locally on my machine.
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.
Did this work?
Co-authored-by: DaniΓ«l van Noord <13665637+DanielNoord@users.noreply.github.com>
No problem, thanks also to you @DanielNoord for the technical help with git. Thanks also to @Pierre-Sassoulas for cleaning up the fiddly bits |
thanks for your kind words.
I voted eyeballs because I don't see a problem with raising two messages for one bad line of code. But I might change my vote if someone can tell my why it could be a problem (maybe it could be a UX concern, I don't know?) |
Co-authored-by: DaniΓ«l van Noord <13665637+DanielNoord@users.noreply.github.com>
Co-authored-by: DaniΓ«l van Noord <13665637+DanielNoord@users.noreply.github.com>
c1afcbc
to
8a363d7
Compare
Co-authored-by: DaniΓ«l van Noord <13665637+DanielNoord@users.noreply.github.com>
What you might want to do is |
Co-authored-by: DaniΓ«l van Noord <13665637+DanielNoord@users.noreply.github.com>
Co-authored-by: DaniΓ«l van Noord <13665637+DanielNoord@users.noreply.github.com>
I've stuffed up again π± Now some tests are failing in CI, even though (some of) these pass locally. I don't think whatever code the CI task runs is always the same as what I've got. |
The information for the line/column in functional tests come from the AST module that we do not control. We're also testing for python 3.8 to 3.10 (The AST got more stable in 3.8). If there's a discrepancy between interpreter for the line/column information coming from the AST we need to examine closely what interpreter changed and take a decision to exclude some interpreter from the check in a generic file or to separate the check by interpreter. |
It seems the expected output for the |
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.
Some last comments about spacing, most have now been fixed. Note that there are also some open comments in pylint/checkers/base/comparison_checker.py
@@ -1,6 +1,6 @@ | |||
'''Assert check example''' | |||
|
|||
# pylint: disable=comparison-with-itself | |||
# pylint: disable=comparison-with-itself comparison-of-constants |
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.
# pylint: disable=comparison-with-itself comparison-of-constants | |
# pylint: disable=comparison-with-itself, comparison-of-constants |
# pylint: disable=missing-docstring, comparison-with-itself | ||
|
||
|
||
if 2 is 2: # [literal-comparison, comparison-of-constants] |
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.
Note that this file still needs to be updated for spaces.
@@ -11,21 +11,21 @@ def foo(): | |||
return True | |||
elif arg <= arg: # [comparison-with-itself] | |||
return True | |||
elif None == None: # [comparison-with-itself] | |||
elif None == None: # [comparison-of-constants, comparison-with-itself] |
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.
Did this work?
@@ -62,9 +62,9 @@ def test_break_in_orelse_deep(): | |||
"""no false positive for break in else deeply nested | |||
""" | |||
for _ in range(10): | |||
if 1 < 2: | |||
if 1 < 2: # pylint: disable=comparison-of-constants |
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.
This file is also missing double spacing.
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.
black doesn't seem to mind about this issue; even if I do pre-commit run --all-files
, the double space doesn't get put in. Does this depend on some kind of configuration, 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.
No, pre-commit
sadly won't fix this for us. We explicitly exclude these test files from pre-commit
: for example, sometimes we want to test that even if there are mistakes our syntactic errors in code pylint
exits gracefully instead of crashing. We don't want pre-commit
to warn us about such "mistakes".
Thus, keeping style in these files is a little harder. Many of the contributors and reviewers have set up their IDE to also run some formatters whenever they save a file. For example, I run black
on save together with an import sorter. This helps keep the style in our test files somewhat similar. However, when people with such "on-save-formatters" look at these test files and make a change their formatters will also change stuff unrelated to the issue they are working on, as the formatter might start sorting imports or formatting lines. So, keeping the general style in our test files not only is a stylistic choice but also helps keep some of our contributors more productive. It's a bit annoying that we need to do this by hand, especially for larger PRs such as this one, but in the long run it tends to make us all more productive π
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.
Oh I get it now. pre-commit
won't do this, by deliberate design. But of course we I could invoke black on those files ourselves.
Anyway I've done it manually
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.
Those file are sometime not black formatted by design, if we run black everywhere we won't have any tests for single quote strings for example. I think we should go easy on the normalization, we want to also catch bugs for users that do not use black or isort or do not respect pep8 to the letter, it's a good thing if the functional tests are somewhat messy.
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, once the point raised by Daniel are resolved ! Thank you for taking a lof of remarks into account already @omarandlorraine.
I added the last changes myself. Thanks for your work here @omarandlorraine and congratulations on writing your first new checker! π |
Yes thanks very much @omarandlorraine ! |
Oh cool! Thanks also to everyone for making this a good experience for me. |
Type of Changes
Description
checker for catching pointless comparisons between two literals
Closes #6076
The Issue mentions tautological and logical errors. But this check is about comparisons between literals, which is a subset of all possible logical errors.