diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index ef92e4a..2372cdb 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -4,6 +4,12 @@ entry: '(?i)# noqa(?!: )' language: pygrep types: [python] +- id: python-check-blanket-nosec + name: check blanket nosec + description: 'Enforce that bandit `nosec` annotations always occur with specific codes. Sample annotations: `# nosec: B101`, `# nosec: B101,B102`' + entry: '# *nosec(?!: *\w)' + language: pygrep + types: [python] - id: python-check-blanket-type-ignore name: check blanket type ignore description: 'Enforce that `# type: ignore` annotations always occur with specific codes. Sample annotations: `# type: ignore[attr-defined]`, `# type: ignore[attr-defined, name-defined]`' diff --git a/README.md b/README.md index ed50484..71e6c83 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ For example, a hook which targets python will be called `python-...`. [generated]: # (generated) - **`python-check-blanket-noqa`**: Enforce that `noqa` annotations always occur with specific codes. Sample annotations: `# noqa: F401`, `# noqa: F401,W203` +- **`python-check-blanket-nosec`**: Enforce that bandit `nosec` annotations always occur with specific codes. Sample annotations: `# nosec: B101`, `# nosec: B101,B102` - **`python-check-blanket-type-ignore`**: Enforce that `# type: ignore` annotations always occur with specific codes. Sample annotations: `# type: ignore[attr-defined]`, `# type: ignore[attr-defined, name-defined]` - **`python-check-mock-methods`**: Prevent common mistakes of `assert mck.not_called()`, `assert mck.called_once_with(...)` and `mck.assert_called`. - **`python-no-eval`**: A quick check for the `eval()` built-in function diff --git a/tests/hooks_test.py b/tests/hooks_test.py index acd774d..df953b4 100644 --- a/tests/hooks_test.py +++ b/tests/hooks_test.py @@ -62,6 +62,37 @@ def test_python_check_blanket_noqa_negative(s): assert not HOOKS['python-check-blanket-noqa'].search(s) +@pytest.mark.parametrize( + 's', + ( + 'x = 1 # nosec', + 'x = 1 # nosec:', + 'x = 1 # nosec: ', + 'x = 1 # nosec # noqa', + ), +) +def test_python_check_blanket_nosec_positive(s): + assert HOOKS['python-check-blanket-nosec'].search(s) + + +@pytest.mark.parametrize( + 's', + ( + 'x = 1', + 'x = 1 # nosec: B101', + 'x = 1 # nosec: B101', + 'x = 1 # nosec: B101,B102', + 'x = 1 # nosec: B101, B102', + 'x = 1 # nosec: B101 B102', + 'x = 1 # nosec:B101 B102', + 'x = 1 # nosec: B101, subprocess_popen_with_shell_equals_true', + 'x = 1 # nosec: B101 subprocess_popen_with_shell_equals_true # noqa', + ), +) +def test_python_check_blanket_nosec_negative(s): + assert not HOOKS['python-check-blanket-nosec'].search(s) + + @pytest.mark.parametrize( 's', (