From daa0acd0bf3ef73f92fb65d39fe49d0b35504318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Lind=20Kristiansen?= Date: Thu, 2 Nov 2023 12:03:31 +0100 Subject: [PATCH] Add compatibility with VS Code October 2023 The October 2023 version of VS Code deprecates built-in linting and formatting features that were shipped with the Python extension. This means linters and formatters will have to run through dedicated extensions. There are currently extensions for Black, Pylint and Flake8, but there are no extensions for Bandit and Pydocstyle. This means they must be run in another way. Luckily there are Flake8 plugins for both Bandit and Pydocstyle. With the changes in this commit, Voight-Kampff now expects the user to use the plugins if they want to run Bandit and Pydocstyle, and consequently the standalone linters are disabled by default when running `vk`. It is still possible to run the linters by explicitly specifying their names as arguments to the `vk` command. Unfortunately, the Bandit Flake8 plugin expects a config file in INI format while Voight-Kampff originally expected a YAML config file for Bandit. For compatibility with the plugin, this commit updates Voight-Kampff to expect an INI file. This breaks backwards compatibility. Further, the functionality for disabling rules are different between the standalone Bandit and the Flake8-plugin. Consequently if, say, the rule that detects for hardcoded passwords is to be disabled inline, it must be done in one way to work with the standalone linter, and in another way to work with the Flake8 plugin. This means any code that disables Bandit rules inline should be updated. Pydocstyle does not suffer from this problem. The Voight-Kampff code itself has been updated to expect both plugins to be installed. --- .bandit | 4 ++-- .circleci/config.yml | 12 +++-------- .vscode/settings.json | 43 ++++++++++++++++----------------------- setup.py | 4 ++-- voight_kampff/__main__.py | 14 +++++++++++-- voight_kampff/task.py | 4 ++-- 6 files changed, 39 insertions(+), 42 deletions(-) diff --git a/.bandit b/.bandit index 1cc4681..a1be520 100644 --- a/.bandit +++ b/.bandit @@ -1,2 +1,2 @@ -skips: - - B101 # assert_used +[bandit] +skips = B101 diff --git a/.circleci/config.yml b/.circleci/config.yml index bda5c70..aba47b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -76,13 +76,10 @@ jobs: command: pip3 install --upgrade pip - run: name: Install linters - command: pip3 install bandit black flake8 pydocstyle pyenchant pylint + command: pip3 install black flake8 pyenchant pylint - run: name: Install Voight-Kampff - command: pip3 install ."[test]" - - run: - name: Bandit - command: vk bandit + command: pip3 install ."[dev]" - run: name: Black command: vk black @@ -92,9 +89,6 @@ jobs: - run: name: Markdownlint command: vk markdownlint - - run: - name: Pydocstyle - command: vk pydocstyle - run: name: Pyright command: vk pyright @@ -120,7 +114,7 @@ jobs: command: pip3 install --upgrade pip - run: name: Install Voight-Kampff - command: pip3 install ."[test]" + command: pip3 install ."[dev]" - run: name: Install pyenchant and pylint command: pip3 install pyenchant pylint diff --git a/.vscode/settings.json b/.vscode/settings.json index 7ce25e2..22ff12a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,14 @@ { + "autoDocstring.startOnNewLine": true, + "coverage-gutters.coverageFileNames": [ + "test-results/voight_kampff/cov-py38.xml" + ], + "coverage-gutters.coverageReportFileName": "test-results/voight_kampff/html/index.html", + "editor.codeActionsOnSave": { + "source.organizeImports": true + }, + "editor.formatOnSave": true, "editor.rulers": [88], - "files.exclude": { "**/.git": true, "**/.mypy_cache": true, @@ -13,33 +21,18 @@ "**/.pytest_cache": true, "**/.ipynb_checkpoints": true }, - - "autoDocstring.startOnNewLine": true, - + "notebook.formatOnSave.enabled": true, "python.analysis.typeCheckingMode": "basic", - - "python.formatting.provider": "black", - - "python.linting.enabled": true, - "python.linting.ignorePatterns": [".vscode/*.py", "**/site-packages/**/*.py"], - "python.linting.banditEnabled": true, - "python.linting.banditArgs": ["-c=.bandit"], - "python.linting.flake8Enabled": true, - "python.linting.flake8Path": "flake8", - "python.linting.pycodestyleEnabled": false, - "python.linting.pydocstyleEnabled": true, - "python.linting.pylintEnabled": true, - "python.linting.pylintCategorySeverity.convention": "Warning", - "python.linting.pylintCategorySeverity.refactor": "Information", - + "python.languageServer": "Pylance", "python.testing.pytestEnabled": true, "python.testing.pytestArgs": [ "--exitfirst", "--verbose", "--cov=./voight_kampff", - "--cov-report=xml:test-results/voight_kampff/cov-py38.xml", - "--cov-report=html:test-results/voight_kampff/html" + "--cov-report=xml:test-results/cov.xml", + "--cov-report=html:test-results/html" ], + "rewrap.autoWrap.enabled": true, "[git-commit]": { "editor.rulers": [50, 72] }, "[markdown]": { "editor.wordWrap": "off", @@ -47,8 +40,8 @@ "editor.acceptSuggestionOnEnter": "off", "editor.defaultFormatter": "esbenp.prettier-vscode" }, - "coverage-gutters.coverageFileNames": [ - "test-results/voight_kampff/cov-py38.xml" - ], - "coverage-gutters.coverageReportFileName": "test-results/voight_kampff/html/index.html" + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter", + "editor.formatOnType": true + } } diff --git a/setup.py b/setup.py index 88f504f..7d3054d 100644 --- a/setup.py +++ b/setup.py @@ -61,11 +61,9 @@ def _validate_version(tag: str | None, version: str) -> bool: keywords="", packages=find_packages(), install_requires=[ - "bandit", "black", "flake8", "isort", - "pydocstyle", "pyenchant", "pylint", ], @@ -73,6 +71,8 @@ def _validate_version(tag: str | None, version: str) -> bool: "dev": [ "coverage", "flake8-annotations", + "flake8-bandit", + "flake8-docstrings", "flake8-plus", "flake8-pytest-style", "pytest-cov", diff --git a/voight_kampff/__main__.py b/voight_kampff/__main__.py index 0c97432..6868ce1 100644 --- a/voight_kampff/__main__.py +++ b/voight_kampff/__main__.py @@ -9,7 +9,7 @@ "bandit": Task( "Bandit", "bandit", - ["-c=.bandit"], + ["--ini", ".bandit"], glob_file_type="py", ), "black": Task( @@ -60,6 +60,16 @@ } LINTER_NAMES = list(LINTER_TASKS.keys()) +DEFAULT_LINTER_NAMES = [ + "black", + "cspell", + "flake8", + "isort", + "markdownlint", + "pylint", + "pylint-spelling", + "pyright", +] def main(): @@ -111,7 +121,7 @@ def __call__( ) unique_values.append(value) if not values: - values = LINTER_NAMES + values = DEFAULT_LINTER_NAMES setattr(namespace, self.dest, values) diff --git a/voight_kampff/task.py b/voight_kampff/task.py index 1631a69..745596d 100644 --- a/voight_kampff/task.py +++ b/voight_kampff/task.py @@ -1,5 +1,5 @@ """Task specification.""" -import subprocess # nosec +import subprocess # noqa: S404 from pathlib import Path from typing import List @@ -51,7 +51,7 @@ def run(self) -> int: """ print(f"🐍 {self.title}{' ' * (30-len(self.title))}", end="", flush=True) files = self._list_files() - process = subprocess.run( # nosec + process = subprocess.run( # noqa: S603 [self._command, *self._args, *files], stdout=subprocess.PIPE, stderr=subprocess.PIPE,