-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add mixin-class-rgx
option
#5203
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
Conversation
for more information, see https://pre-commit.ci
Pull Request Test Coverage Report for Build 1377657716
💛 - Coveralls |
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.
👍 Nice option !
@Pierre-Sassoulas What do you think about the question posed in the PR description? |
I think we're doing that because a Mixin need to have attribute defined outside init so it would be a false positive if we raise a warning for that in a mixin ? For |
Ah yeah, I forgot about the outside of |
After reading the code I think someone thought ignore mixin was an option to ignore everything for mixin ? Must have had a very troublesome mixin class 😄 I think we can remove, thank you for catching that problem. |
I will submit a different PR to remove it and then remove the tests here. Edit: @Pierre-Sassoulas do you want me to remove the check for |
I did not see the |
# Ignore mixin classes if they match the rgx option. | ||
if self._ignore_mixin_members and self._mixin_class_rgx.match( | ||
inferred.name | ||
): | ||
continue |
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.
# Ignore mixin classes if they match the rgx option. | |
if self._ignore_mixin_members and self._mixin_class_rgx.match( | |
inferred.name | |
): | |
continue | |
# Ignore mixin classes if they match the rgx option. | |
if self._mixin_class_rgx.match( | |
inferred.name | |
): | |
continue |
or
# Ignore mixin classes if they match the rgx option. | |
if self._ignore_mixin_members and self._mixin_class_rgx.match( | |
inferred.name | |
): | |
continue |
@Pierre-Sassoulas I meant either removing all checks for mixim's (so both mixin_members
and the regex
) or only removing the members check
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.
OK, I understand now. I'll try to see why it was added in the first place, there must be a reason.
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's like that since the beginning of time and I don't see any explanation. 24e9d35#diff-76ab71e7eb3954c60b39e11f3dfe5cc45ee2b139c7738dfbca1566b8d50cf0b8R71
But now that I think of it, It might be to avoid false positive when the mixin is actually an async manager even if the current class is not. It's impossible to know that without analyzing the class that are supposed to be mixed. So in fact I think we should keep it. 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.
That is probably the reason why "they" did this initially. However, I think that might warrant a change of the ignore_mixin_members
option name to something like ignore_mixin_class_checks
. That would be something for a different PR, but this name really does not fit what it is doing right now.
Is there a "old-name" system for option names?
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 should use the new regex pattern only in order to check if a class is supposed to be a mixin and drop the other check.
ignore-mixin-members=yes | ||
|
||
# Regex pattern to define which classes are considered mixins. |
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.
# Regex pattern to define which classes are considered mixins. | |
# Regex pattern to define which classes are considered mixins and should be | |
exempted from certain checks. |
@Pierre-Sassoulas Agree, but then let's add this. Perhaps we should also keep a list of exempted checks somewhere.. I don't know of a good place though.
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.
Maybe it should be a configurable option ? Also it seems we're skipping the check after doing all the calculations. We might want to skip the check as soon as we detect a mixin.
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 about removing ignore-members
and adding a new option ignore-checks-for-mixin
which would be a comma separated list of checks that exclude Mixin? We could add the supported checks to the description of that option.
I think I have already thought of good way to deprecate an option.
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, don't you prefer ignored-checks-for-mixin
though ?
We already "deprecated" an option with blacklist/whitelist at some point #3961. I think the plan is to handle both until the end of time so users have no need to upgrade their configuration. There's no warning either for the same reason. Having to upgrade the configuration is bothersome with so many pylintrc in the wild already. I guess you had a different idea on how to do that ? I guess if the change isn't political it will attracts trolls less.
I think that if we don't want to maintain all of the legacy options we might have to put a configuration upgrader into place (so the migration to the new configuration file is automated). It could work well with the need of using a single possible configuration file (instead of pylintrc, .pylintrc, setup.cfg, pyproject.toml, ~/.pylintrc) and it will probably be only pyproject.toml
in the long 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.
Right, don't you prefer
ignored-checks-for-mixin
though ?
👍
We already "deprecated" an option with blacklist/whitelist at some point #3961. I think the plan is to handle both until the end of time so users have no need to upgrade their configuration. There's no warning either for the same reason. Having to upgrade the configuration is bothersome with so many pylintrc in the wild already. I guess you had a different idea on how to do that ? I guess if the change isn't political it will attracts trolls less.
I think that if we don't want to maintain all of the legacy options we might have to put a configuration upgrader into place (so the migration to the new configuration file is automated). It could work well with the need of using a single possible configuration file (instead of pylintrc, .pylintrc, setup.cfg, pyproject.toml, ~/.pylintrc) and it will probably be only
pyproject.toml
in the long term.
I think we should only do a configuration upgrader after have moved to argparse
.
I intend to support both indeed, but with a deprecation warning when we notice ignore-members
is being 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.
Sure, an upgrader wouldn't make sense as long as we still have optparse and aren't clear about what we want to deprecate. I'm not even sure if I want to have only pyporject.toml in 3.0. Just giving you the long term picture here :)
I intend to support both indeed, but with a deprecation warning when we notice ignore-members is being used
Sounds good. If the option is not being used by pylint but exists it's logical that we warn. Maybe we can suggest the option that replaced it in the warning so the user can copy paste the next conf ? It's not an upgrader, but it's close so we could create the base class for the upgrader and use it to get the recommendation ? :)
Something like:
class ConfigurationUpgrader:
def next_value(option_name:str, value: Any) -> [str, any]:
next_for_option_name = getattr(f"next_value_for_{option_name.replace('-', '_')}", None)
if next_for_option_name:
return next_for_option_name(value)
return option_name, value
def next_value_for_ignore_members(value: Any);
return 'mixin-class-rgx", [".*Mmixin"]
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 toyed around with this, but it turned out to be a little bit more difficult than I initially thought.
They way we're loading options makes it really difficult to deprecate them and emit warnings for when users still use them.
They need to have an optdict
in one of the checkers, but then we also load the option every time ourselves. Catching the option and changing it directly to the new name is also difficult as we would need to create combinations of every validator type with every other validator type (ie., to be able to translate a "yes-no" option to a "list of strings" option.
I think we should leave this as is, open an issue to track this and wait for the move to argparse
. I hope that module provides better ways to do this.
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.
Thank you for trying ! Do you think we should change the design of the options so that we're passing an object (argparse.Namespace
?) to the checker at initialization ?
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 ideally we wouldn't work with any OptionsProviders
at all and just load all possible options from a large dict of optdict
s (or Argument
s as suggested in #5152) at start up once and subsequently load the user defined options/overwrites.
I found that the load_defaults
function was called 2/3 times for one single test and the whole concept of OptionsProviders
creates numerous problems when different checker classes need to access the same option. (See #5195).
As indicated in #4814 option processing take a considerable time for our start-up, which I can imagine is because of stuff like calling load_defaults
twice.
The get_global_option
function is basically trying to circumvent this design of OptionProviders
, as it turns out it is often much more logical to make options "global" for all checkers.
I don't know what the initial objective of OptionProviders
was and I think we will likely run into unexpected problems when we would move to such a design, but from my experience with our config
module this might in the end be much more maintainable.
doc/whatsnew/<current release.rst>
.Type of Changes
Description
Adds a new option
mixin-class-rgx
which allows users to set a pattern that their mixin class names should adhere to.I think we might need to reconsider whether the
ignore-mixin-members
option should be checked for thenot-async-context-manager
andattribute-defined-outside-init
messages. I've added tests for them because it currently is, but the name of that option and the description of it doesn't really imply it should.Supersedes #3719