-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Switch from pylint to flake8 #1179
Comments
The python version used for pylint can effect results returned, pylint is very sensitive to the environment it's run in. Running on python 3.5 which is the oldest supported python version masks issues on newer python versions. For example, if you have python 3.7 installed locally lint will always fail becaues of changes to the stdlib. This starts to become more of an issue as a particular python version ages, since the user and contributor base moves to newer versions of python. This commit changes the version of pylint we run in CI to 3.7 to tests the leading edge instead of the trailing so we keep our pylint testing up to date with the python versions we support. Related to Qiskit#3127 and Qiskit#1179
* Bump lint jobs to latest stable python version The python version used for pylint can effect results returned, pylint is very sensitive to the environment it's run in. Running on python 3.5 which is the oldest supported python version masks issues on newer python versions. For example, if you have python 3.7 installed locally lint will always fail becaues of changes to the stdlib. This starts to become more of an issue as a particular python version ages, since the user and contributor base moves to newer versions of python. This commit changes the version of pylint we run in CI to 3.7 to tests the leading edge instead of the trailing so we keep our pylint testing up to date with the python versions we support. Related to #3127 and #1179 * Add **kwargs to avoid linter error The abc.ABCMeta class defition added a **kwargs to the __new__ method definition in python 3.6. This breaks the linter because the qiskit.pulse.commands.command.MetaCount subclass function signature differs from stdlib on newer python versions. This works around this by adding a throwaway kwargs argument to the signature so that we pass pylint's blind pedantry when running on newer python versions, but still work with python 3.5.
* Bump lint jobs to latest stable python version The python version used for pylint can effect results returned, pylint is very sensitive to the environment it's run in. Running on python 3.5 which is the oldest supported python version masks issues on newer python versions. For example, if you have python 3.7 installed locally lint will always fail becaues of changes to the stdlib. This starts to become more of an issue as a particular python version ages, since the user and contributor base moves to newer versions of python. This commit changes the version of pylint we run in CI to 3.7 to tests the leading edge instead of the trailing so we keep our pylint testing up to date with the python versions we support. Related to Qiskit#3127 and Qiskit#1179 * Add **kwargs to avoid linter error The abc.ABCMeta class defition added a **kwargs to the __new__ method definition in python 3.6. This breaks the linter because the qiskit.pulse.commands.command.MetaCount subclass function signature differs from stdlib on newer python versions. This works around this by adding a throwaway kwargs argument to the signature so that we pass pylint's blind pedantry when running on newer python versions, but still work with python 3.5.
Hello @Bhargavishnu . Black is a very nice formarter. But it's not a linter. By the way, Pylint 2.6 is more compatible with Black.
|
Since we moved to black, is this issue still relevant? |
closing due lack of activity and given that is probably not relevant any more. Please, reopen if needed it. |
It is, pylint is still being run and has all the same issues outlined above. Black just made code formatting automatic for us. |
Here is one specific problem with pylint. It could be avoided by disabling the particular rule. Or disabling the rule locally (which would be almost every instance that it is flag). Or use something other than pylint. (Or petition pylint to change) pylint flags false positives (a lot of them) for
In summary, I can't tell where this documentation requirement came from. It is not in any relevant (google and numpy) style guide. EDIT: (there are some who support documenting all exceptions, more in java, php, but also some in python) There is no reference or rationale given. Verifying that an API is adequately documented is very difficult. Determining if a Here is a discussion of documenting thrown exceptions I think the topic is open invites polemics. For example in a comment from the post above:
But, it ought to be able to resolve this without violating a COC. Here is an opinion in the context of PHP. They say to document all exceptions. But all the examples given would be allowed by google and numpy styles. Here is an argument for documenting all exceptions. I may know the API of the function I'm calling. And I can expect an exception to be thrown if I violate it. But, I don't know which exception is thrown. Eg If I pass an |
Here is a partial audit. "wrong" means an entry in If I find any that are correct, I'll mark them with "correct". The vast majority of these involve validation of input data and raising an exception if characteristics of the input data violate the API. Usually, the API is not well documented (because the linter isn't clever enough to detect this and prevent merging the PR) Often the required Raises doc serves as a poor, cryptic substitute for documentation of the API.
|
The earlier config update wasn't sufficient to get pylint to ignore all retworkx usage. This commit adds additional config entries for retworkx to try and get pylint to exclude it more thoroughly. Additionally, even with these global excludes on pylint there are a few places in the code where additional manual rule disabling was needed to get pylint to pass (further evidence for Qiskit#1179).
* Add retworkx to generated module list in the .pylintrc With the recent release of retworkx 0.12.0 the package has been renamed to rustworkx. For compatibility the retworkx python namespace continues to work and instead it just redirects imports to the new name. However, pylint is unable to reason about this dynamic import redirecting which causes it to fail in CI. While in 0.23.0 we'll update the requirement to the rustworkx name in order to unblock CI for the pending 0.22.0 release this commit adds the retworkx namespace to the list of generated modules which tells pylint to try not to detect members of the module. * Expand config and add inline excludes where needed The earlier config update wasn't sufficient to get pylint to ignore all retworkx usage. This commit adds additional config entries for retworkx to try and get pylint to exclude it more thoroughly. Additionally, even with these global excludes on pylint there are a few places in the code where additional manual rule disabling was needed to get pylint to pass (further evidence for #1179).
* Add retworkx to generated module list in the .pylintrc With the recent release of retworkx 0.12.0 the package has been renamed to rustworkx. For compatibility the retworkx python namespace continues to work and instead it just redirects imports to the new name. However, pylint is unable to reason about this dynamic import redirecting which causes it to fail in CI. While in 0.23.0 we'll update the requirement to the rustworkx name in order to unblock CI for the pending 0.22.0 release this commit adds the retworkx namespace to the list of generated modules which tells pylint to try not to detect members of the module. * Expand config and add inline excludes where needed The earlier config update wasn't sufficient to get pylint to ignore all retworkx usage. This commit adds additional config entries for retworkx to try and get pylint to exclude it more thoroughly. Additionally, even with these global excludes on pylint there are a few places in the code where additional manual rule disabling was needed to get pylint to pass (further evidence for #1179). (cherry picked from commit 2f40849)
* Add retworkx to generated module list in the .pylintrc With the recent release of retworkx 0.12.0 the package has been renamed to rustworkx. For compatibility the retworkx python namespace continues to work and instead it just redirects imports to the new name. However, pylint is unable to reason about this dynamic import redirecting which causes it to fail in CI. While in 0.23.0 we'll update the requirement to the rustworkx name in order to unblock CI for the pending 0.22.0 release this commit adds the retworkx namespace to the list of generated modules which tells pylint to try not to detect members of the module. * Expand config and add inline excludes where needed The earlier config update wasn't sufficient to get pylint to ignore all retworkx usage. This commit adds additional config entries for retworkx to try and get pylint to exclude it more thoroughly. Additionally, even with these global excludes on pylint there are a few places in the code where additional manual rule disabling was needed to get pylint to pass (further evidence for #1179). (cherry picked from commit 2f40849) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
At this point, it might be better to skip flake8 and jump straight to ruff 🙂 I ended up here because I hit a bug in the currently pinned version of pylint with a code change I made. I noticed that the pinned version was quite old (almost two years). I tried to update it and found that many new issues were flagged. I was curious how the pylint rules were chosen for qiskit in order to know whether the new issues should be fixed or ignored and ended up here. For my personal case, I will just pylint ignore the line that was flagged. In my experience, what distinguishes pylint from flake8 is that pylint makes an effort to inspect attribute access and function calls for correctness while flake8 only flags issues with the syntax of the code. So flake8 flags things like undefined variables and f-strings without formatted variables, while pylint will flag a function called with too many arguments. One tradeoff in these approaches is that pylint must be run in the environment that the package is installed in while flake8 can run on any Python code. Also, flake8 only evaluates files individually, so it does well for incremental checks and parallelizing while pylint needs to parse more files to process a single file. In the past couple years, pylint has tried to shift to disabling a lot of the more annoying checks by default. Maybe the qiskit pylintrc is out of date with that direction. Still it can be annoying to keep up with new rules added in new versions of pylint. One option is to run with |
I was not familiar with As for the differences between pylint and flake8, at least when I opened this issue almost 5 years ago I felt (and still feel this way today) that the extra level of inspection that pylint provides wasn't worth the slow execution or the other issues I outlined in the OP. At the time I failed to get a consensus around this, and it fell of my radar in the intervening years. I still feel moving to either flake8 or now |
This issue can be closed now, right? |
What is the expected enhancement?
The pylint tool is overly pedantic, it fails over things like variable names and often is more of an annoyance than a helpful tool for enforcing consistent style in a repo. You can just look to how many of our source files have to explicitly exclude rules because they just get in the way. Alternatively we can/should use the flake8 project: http://flake8.pycqa.org/en/latest/ to enforce style (it's worth pointing out that they're both maintained by the same team). It is much more forgiving as it is more about enforcing just pep8 and some other common rules. It also integrates nicely with tox so we can use that to define our base set of rules.
The text was updated successfully, but these errors were encountered: