[BUG] noqa comment is prewhen the tool runs from a pre-commit hook
Describe the bug
I introduced pre-commit into a project in order to keep human error out of code cleanliness, and used my long trusted and used prospector as a hook.
I have been using prospector to manually do the linting on my code before. Using the noqa comments is ideal, because my IDE of choice is PyCharm, and the noqa comments suppress the code inspection in PyCharm too.
After running the pre-commit hooks, however, I noticed that pylint still stubbornly ignores these noqa comments even after the solution of #49.
To Reproduce
- Consider important_code.py:
this_constant_is_not_named_right = True # noqa: invalid-name
class Dummy:
def this_method_could_be_static(self): # noqa: no-self-use
return True
- Run prospector manually from the cli
$ poetry run prospector --with-tool bandit
Check Information
=================
Started: 2022-06-07 18:29:51.207686
Finished: 2022-06-07 18:29:55.552712
Time Taken: 4.35 seconds
Formatter: grouped
Profiles: .prospector.yaml, no_doc_warnings, no_test_warnings, strictness_high, strictness_veryhigh, no_member_warnings
Strictness: from profile
Libraries Used:
Tools Run: bandit, dodgy, mccabe, profile-validator, pycodestyle, pyflakes, pylint
Messages Found: 0
External Config: pylint: D:\path\to\my\project\pyproject.toml
- Run prospector with the pre-commit hooks
$ poetry run pre-commit run --all-files
black....................................................................Passed
isort....................................................................Passed
fix end of files.........................................................Passed
trim trailing whitespace.................................................Passed
check for added large files..............................................Passed
check yaml...............................................................Passed
debug statements (python)................................................Passed
check blanket noqa.......................................................Passed
flake8...................................................................Passed
prospector with bandit...................................................Failed
- hook id: prospector-with-bandit
- exit code: 1
Messages
========
src\important_code.py
Line: 1
pylint: invalid-name / Constant name "this_constant_is_not_named_right" doesn't conform to UPPER_CASE naming style
Line: 5
pylint: no-self-use / Method could be a function (col 4)
Check Information
=================
Started: 2022-06-07 18:30:12.037330
Finished: 2022-06-07 18:30:16.852370
Time Taken: 4.82 seconds
Formatter: grouped
Profiles: .prospector.yaml, no_doc_warnings, no_test_warnings, strictness_high, strictness_veryhigh, no_member_warnings
Strictness: from profile
Libraries Used:
Tools Run: bandit, dodgy, mccabe, profile-validator, pycodestyle, pyflakes, pylint
Messages Found: 2
External Config: pylint: D:\path\to\my\project\pyproject.toml
Expected behavior
The output of prospector is consistent, ignoring the errors thrown by pylint on the lines commented with noqa.
Environment (please complete the following information):
- OS: Windows 10 (PowerShell)
- Environment manager: Poetry version 1.1.11
- Tool: pylint
- Prospector version: 1.7.7
- Python version: Python 3.10.4
- Pre-commit version: 2.19.0
Additional context .prospector.yaml
output-format: grouped
strictness: high
test-warnings: false
doc-warnings: false
mccabe:
options:
max-complexity: 10
pycodestyle:
full: true
options:
max-line-length: 120
pylint:
enable:
- C0322
- C0323
- C0324
- E1103
- I0014
- bad-classmethod-argument
- bad-mcs-classmethod-argument
- bad-mcs-method-argument
- exec-used
- multiple-statements
- no-self-argument
- superfluous-parens
- too-many-lines
- too-many-return-statements
- unused-format-string-key
options:
max-line-length: 120
max-args: 8
max-attributes: 10
.pre-commit-config.yaml
# To install the git pre-commit hook run:
# pre-commit install
# To update the pre-commit hooks run:
# pre-commit install-hooks
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: local
hooks:
- id: black
name: black
description: "Black: The uncompromising Python code formatter"
language: python
entry: poetry run black .
types: [python]
require_serial: true
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
- id: check-yaml
- id: debug-statements
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:
- id: python-check-blanket-noqa
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
hooks:
- id: flake8
args:
- --max-line-length=120
- repo: local
hooks:
- id: prospector-with-bandit
name: prospector with bandit
description: Analyze Python code using Prospector with Bandit
language: python
entry: poetry run prospector --with-tool bandit
types: [python]
require_serial: true
A workaround I have found so far is to use the # pylint: disable=<pylint error code> comment, which produces consistent outputs in both CLI and pre-commit contexts.
This however doesn't disable PyCharm's in-editor code inspection. To do that I have to use both the # noqa: and the # pylint: disable= comments on the same line as below.
this_constant_is_not_named_right = True # noqa: invalid-name # pylint: disable=invalid-name
This unfortunately is quite ugly, because it adds at least 30 characters to the line length.
I am experiencing similar behavior under Windows (works fine on Linux). After some digging, it seems to come down to path separators. As prospector uses paths as dictionary keys in https://github.com/PyCQA/prospector/blob/master/prospector/suppression.py and https://github.com/PyCQA/prospector/blob/master/prospector/postfilter.py using a mix of Windows and Linux style path separators leads to a key mismatch. I am not sure what the root cause of the mismatch is but
prospector -t pyflakes command_line/entrypoint.py
Messages
========
command_line\entrypoint.py
Line: 11
pyflakes: F401 / 'settings' imported but unused (col 1)
Check Information
=================
...
prospector -t pyflakes command_line\entrypoint.py
Check Information
=================
...
Adding
filepath = os.path.normpath(filepath)
after lines 92 and after line 111 in suppression.py and changing line 32 in postfilter.py to
relative_message_path = os.path.normpath(os.path.relpath(message.location.path))
appears to solve the problem.
Is there a better place to "normalize" the paths or is that a reasonable solution?
See #557 and #580