-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: scope wrong-import-position pragma to specific line only #10590
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
base: main
Are you sure you want to change the base?
Conversation
Codecov Reportβ
All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10590 +/- ##
=======================================
Coverage 95.95% 95.95%
=======================================
Files 176 176
Lines 19455 19455
=======================================
Hits 18668 18668
Misses 787 787
π New features to boost your workflow:
|
This comment has been minimized.
This comment has been minimized.
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'm wondering if the 'right way to fix this' isn't to return uninferable in astroid instead. Because it's possible that a function validly return an empty list.
@Pierre-Sassoulas Should it be fixed in the astroid library itself or using an astroid hook in pylint library? |
Astroid itself, we're the same maintainers and 99% of astroid user are also pylint users :) |
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
28128d9
to
8cace41
Compare
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
dd9aafb
to
a7e937a
Compare
for more information, see https://pre-commit.ci
@Pierre-Sassoulas thanks for the guidance! I opened a PR in the astroid repo for this issue. Since this PR is already open, I also included a fix for another pylint issue. Apologies for the force push π |
π€ According to the primer, this change has no effect on the checked open source code. π€π This comment was generated for commit f957d35 |
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 the PR!
In the future it would be better to open a new one as that makes communication scoped a bit better. We can still continue with this one though :)
import json # pylint: disable=wrong-import-position | ||
|
||
# Test that subsequent imports are not affected by the pragma above | ||
import csv # [wrong-import-position] | ||
import re # [wrong-import-position] |
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'm not sure if this is the correct behaviour, or at least should be considered a breaking change?
The test you're changing above seems to explicitly test for this case:
A previous disable should also count for subsequent imports.
@Pierre-Sassoulas What do you think?
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.
Ha, yes, we reviewed independently but I think we said the same thing..
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.
@Pierre-Sassoulas You approved, but this question still stands I guess? We're now actively removing support for behaviour for which we had a test. I'm not sure why we added this behaviour in the first place, but considering we are changing behaviour isn't this a breaking change?
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.
Right, we didn't say the same thing after all. It seems we can't have an easy implementation of both "disable on a statement" and "any disable prevent all further wrong-import-position" so there's a decision to take here. And we might have to do the hard implementation, especially since I don't think isort or ruff deal with intertwined statements in imports (?).
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.
Current PR does:
The fix changes the message enablement check from using the first non-import node's line number to using the current import node's line number, ensuring proper pragma isolation.
Perhaps we can it to:
The fix changes the message enablement check from no longer working on non-import statements for this message. A pragma will disable from the current import statement until further statements, ensuring proper pragma isolation.
if self.linter.is_message_enabled( | ||
"wrong-import-position", self._first_non_import_node.fromlineno | ||
): | ||
if self.linter.is_message_enabled("wrong-import-position", node.fromlineno): |
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.
Instinctively I would say the fix need to be a lot more complex than that. If one line is disabled it means not only that the message shouldn't be raised for it but also that other line should not raise if the only issue for them it the disabled line.
i.e. the expected is
import a
import b
import c
import b # [wrong-import-position]
import a # [wrong-import-position]
import c
import b # pylint: disable=wrong-import-position
import a
import c
import b # pylint: disable=wrong-import-position
import c # [wrong-import-position]
import a # [wrong-import-position]
Tbf, I don't think we should sweat other this, maybe we need to abandon the pylint disable system for this specific error message, and take the isort/ruff "I" disable into account, or drop the message entirely, or integrate ruff plus autofix and drop isort, or integrate both ruff and isort... I don't see a fix for this being super impactful in the mid term.
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 don't fully understand your comment, and I think taking into accounts other tools setting is bit too much work for @emmanuel-ferdman π
@emmanuel-ferdman Do you think we can fix your issue while still keeping the behaviour as being tested in the test? I agree that a disable on a non-import makes no sense, but perhaps we can fix it with a smaller scope?
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.
What I mean is that the effort to fix this at all is not worth it as we have ruff and isort for reordering import, having working disable in pylint or coordinating multiple tools that check this message does not bring a lot of value imo. (Maybe we can even remove the check entirely for 4.0)
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.
@DanielNoord @Pierre-Sassoulas Thanks for the feedback π
From issue #10589 and seeing that other pylint rules are line-based, I assumed this was a bug. But I understand that wrong-import-position
might be different since it's about import ordering patterns. What should we do here? I'm happy to try and implement whatever you think is best.
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.
Sorry for marking an issue as ready for PR when clearly it wasn't well specified @emmanuel-ferdman. Or thank you for making the fix and making us realize what actually fixing this bug imply. I think we should close because there's probably better use for your time. Right now I'm more and more convinced that we should either drop isort and wrong-import-position (import time at startup could make this a big change for users) or add ruff (using ruff and isort as optional dependencies instead of isort as mandatory dependency would open a world of possibilities once the wrong-import-position
proof of concept is validated). In all case this mean this fix is not going to be used much. Need some other maintainers opinion about it and it's probably an idea for pylint 5.0 anyway (that I should open an issue for if Daniel don't think it's trash).
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 agree with removing the dependency on isort
.
It fails logical to let those concerns be dealt with by a separate tool with its own configuration and/or ignores. Wondering what other maintainers think.
@Pierre-Sassoulas, you gave 4 examples above (importing a, b, & c). The original bug report is about wrong-import-position, which maybe doesn't require sorting & other complexities? At any rate, thanks for taking my report seriously, I appreciate that! :) |
Ha, indeed you're right, my bad. Well the fix LGTM as is after a second take. I'm going to create an issue for the unrelated discussion. |
Sorry to risk additional confusion. I will try hard to be clear. However, during the above conversation, I agreed with the expectations of a different condition, C0411 wrong-import-order, as shown with importing a, b, & c in different orders.
which seemed reasonable. But OTOH, this also seems reasonable to the user:
So, which is actually implemented? Easy to check...
I DO get C0411 when I, for example, import a third-party lib in the wrong place.
Maybe C0411 doesn't attempt to validate the "alphabetical" sort order recommendation of PEP 8, and concerns itself only with whether the three sets of imports are correctly organized per PEP 8 like (1) standard lib imports, (2) related 3rd party lib imports (3) Local application/library specific imports. |
Type of Changes
Description
Previously, a
# pylint: disable=wrong-import-position
pragma on a non-import statement would incorrectly suppress wrong-import-position messages for all subsequent import statements in the module. This violated the expected behavior where single-line pragmas should only affect their own line. The fix changes the message enablement check from using the first non-import node's line number to using the current import node's line number, ensuring proper pragma isolation.Example:
Expected Output:
wrong-import-position
messages (incorrect behavior)wrong-import-position
messages for bothimport os
andimport sys
(correct behavior)Closes #10589