From d93fc99edcf0bb55f5c3f4b43a4609fe4586aab4 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Mon, 15 Sep 2025 11:31:17 +0100 Subject: [PATCH] fix: ruff, mypy and pylint violations Fixes: #2039 --- .pre-commit-config.yaml | 136 ++++++------------- pyproject.toml | 7 +- src/ansible_navigator/utils/compatibility.py | 6 +- src/ansible_navigator/utils/json_schema.py | 20 +-- tests/integration/_common.py | 2 +- 5 files changed, 62 insertions(+), 109 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a3b34367d..50ee5ae5c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,86 +1,46 @@ ---- ci: - # We rely on renovate to update it but there is no way to fully disable it - # https://github.com/pre-commit-ci/issues/issues/83 autoupdate_schedule: quarterly skip: - - renovate-config-validator # container limits + - renovate-config-validator default_language_version: - # ensures that we get same behavior on CI(s) as on local machines python: python3.11 -exclude: > - (?x)^( - _readthedocs| - .tox - )$ +exclude: "(?x)^(\n _readthedocs|\n .tox\n)$\n" repos: - repo: https://github.com/renovatebot/pre-commit-hooks - rev: 41.113.0 + rev: 41.113.6 hooks: - id: renovate-config-validator alias: renovate - args: [--strict] + args: + - --strict - repo: https://github.com/rbubley/mirrors-prettier - rev: "v3.6.2" + rev: v3.6.2 hooks: - id: prettier - # Original hook implementation is flaky due to *several* bugs described - # in https://github.com/prettier/prettier/issues/12364 - # a) CI=1 needed to avoid incomplete output - # b) two executions are needed because --list-different works correctly - # only when run with --check as with --write the output will also - # include other entries and logging level cannot be used to keep only - # modified files listed (any file is listes using the log level, regardless if - # is modified or not). - # c) We avoid letting pre-commit pass each filename in order to avoid - # runing multiple instances in parallel. This also ensures that running - # prettier from the command line behaves identically with the pre-commit - # one. No real performance downsides. - # d) exit with the return code from list-different (0=none, 1=some) - # rather than the write (0=successfully rewrote files). pre-commit.ci - entry: env CI=1 bash -c "prettier --list-different . || ec=$? && prettier --loglevel=error --write . && exit $ec" + entry: + env CI=1 bash -c "prettier --list-different . || ec=$? && prettier + --loglevel=error --write . && exit $ec" pass_filenames: false args: [] additional_dependencies: - prettier - prettier-plugin-toml - - repo: https://github.com/pappasam/toml-sort rev: v0.24.3 hooks: - id: toml-sort-fix - - repo: https://github.com/tox-dev/tox-ini-fmt rev: 1.6.0 hooks: - id: tox-ini-fmt - - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.13.0" - hooks: - - id: ruff - entry: sh -c 'ruff check --fix --force-exclude && ruff format --force-exclude' - types_or: [python, pyi] - - repo: https://github.com/streetsidesoftware/cspell-cli rev: v9.2.0 hooks: - id: cspell name: Spell check with cspell - - - repo: https://github.com/Lucas-C/pre-commit-hooks.git - rev: v1.5.5 - hooks: - - id: remove-tabs - exclude: > - (?x)^( - .config/pylint-baseline.txt - )$ - - repo: https://github.com/pre-commit/pre-commit-hooks.git rev: v6.0.0 hooks: - # Side-effects: - id: trailing-whitespace - id: check-merge-conflict - id: end-of-file-fixer @@ -90,84 +50,71 @@ repos: - id: check-case-conflict - id: check-symlinks - id: check-yaml - exclude: > - (?x)^ - ( - mkdocs.yml - ) - $ + exclude: "(?x)^\n (\n mkdocs.yml\n )\n$\n" - id: detect-private-key - # Heavy checks: - id: check-ast - id: debug-statements - - repo: https://gitlab.com/bmares/check-json5 - # Allow json comments, trailing commas - # https://github.com/pre-commit/pre-commit-hooks/issues/395 rev: v1.0.0 hooks: - id: check-json5 - - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.45.0 hooks: - id: markdownlint - exclude: > - (?x)^ - ( - \.github/ISSUE_TEMPLATE/\w+| - docs/( - faq| - index| - )| - README| - src/ansible_navigator/data/(help|welcome) - )\.md - $ - + exclude: + "(?x)^\n (\n \\.github/ISSUE_TEMPLATE/\\w+|\n docs/(\n faq|\n + \ index|\n )|\n README|\n src/ansible_navigator/data/(help|welcome)\n + \ )\\.md\n$\n" - repo: https://github.com/codespell-project/codespell rev: v2.4.1 hooks: - id: codespell - # NOTE: dout is part of the stdout action regex - args: ["-L", "dout"] - # We exclude generated and external files as they are not directly under - # our control, so we cannot fix spelling in them. - exclude: > - (?x)^ - ( - tests/fixtures/integration/actions/.*\.json| - src/ansible_navigator/data/grammar/.*\.json - ) - $ - + args: + - -L + - dout + exclude: + "(?x)^\n (\n tests/fixtures/integration/actions/.*\\.json|\n + \ src/ansible_navigator/data/grammar/.*\\.json\n )\n$\n" - repo: https://github.com/adrienverge/yamllint.git rev: v1.37.1 hooks: - id: yamllint args: - --strict - types: [file, yaml] - + types: + - file + - yaml - repo: https://github.com/PyCQA/flake8.git rev: 7.3.0 hooks: - id: flake8 language_version: python3 additional_dependencies: - - flake8-docstrings # uses pydocstyle - + - flake8-docstrings - repo: https://github.com/jsh9/pydoclint rev: 0.7.3 hooks: - id: pydoclint - - repo: https://github.com/asottile/pyupgrade - # keep it after flake8 rev: v3.20.0 hooks: - id: pyupgrade - args: ["--py310-plus"] + args: + - --py310-plus + - repo: https://github.com/pappasam/toml-sort + rev: v0.24.2 + hooks: + - id: toml-sort-fix + alias: toml + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.13.0 + hooks: + - id: ruff-format + alias: ruff + - id: ruff-check + alias: ruff - repo: https://github.com/pre-commit/mirrors-mypy.git rev: v1.18.1 hooks: @@ -182,9 +129,8 @@ repos: - types-docutils - types-mock - types-PyYAML - - types-setuptools # Needed logging version + - types-setuptools - types-typed-ast - - repo: https://github.com/pycqa/pylint.git rev: v3.3.8 hooks: @@ -197,7 +143,7 @@ repos: - ansible-core - ansible-runner - astroid - - dill>=0.3.6 # needed for py311 + - dill>=0.3.6 - jinja2 - jsonschema - libtmux diff --git a/pyproject.toml b/pyproject.toml index d9e198ae9..09ed1c9be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -122,6 +122,7 @@ disable = [ "too-few-public-methods", "unsubscriptable-object", "unknown-option-value", + "CPY001", # copyright notice at top of file # https://gist.github.com/cidrblock/ec3412bacfeb34dbc2d334c1d53bef83 "C0103", # invalid-name / ruff N815 "C0105", # typevar-name-incorrect-variance / ruff PLC0105 @@ -344,10 +345,13 @@ disable = [ enable = [ "useless-suppression" # Identify unneeded pylint disable statements ] +# disabled "useless-suppression" on fail-on due to conflict with needed deprecated-class on older python versions fail-on = [ - "useless-suppression" ] +[tool.pylint.reports] +score = false + [tool.pytest.ini_options] # do not add xdist options here as this will make running of a single test and # debugging hard. @@ -371,6 +375,7 @@ builtins = ["__"] exclude = ["tests/fixtures/**", ".git"] fix = true line-length = 100 +unsafe-fixes = true [tool.ruff.lint] ignore = [ diff --git a/src/ansible_navigator/utils/compatibility.py b/src/ansible_navigator/utils/compatibility.py index 7688f89ad..510e15e52 100644 --- a/src/ansible_navigator/utils/compatibility.py +++ b/src/ansible_navigator/utils/compatibility.py @@ -8,10 +8,10 @@ from typing import TypeAlias -if sys.version_info < (3, 11): - from importlib.abc import Traversable -else: +if sys.version_info >= (3, 11): from importlib.resources.abc import Traversable +else: + from importlib.abc import Traversable # pylint: disable=deprecated-class __all__ = ["Traversable", "TypeAlias", "importlib_metadata"] diff --git a/src/ansible_navigator/utils/json_schema.py b/src/ansible_navigator/utils/json_schema.py index 526a7b132..03d340c36 100644 --- a/src/ansible_navigator/utils/json_schema.py +++ b/src/ansible_navigator/utils/json_schema.py @@ -4,6 +4,7 @@ import json +from collections import deque from dataclasses import dataclass from typing import TYPE_CHECKING from typing import Any @@ -16,10 +17,10 @@ if TYPE_CHECKING: - from collections import deque + from collections.abc import Sequence -def to_path(schema_path: deque[Any]) -> str: +def to_path(schema_path: Sequence[Any] | str) -> str: """Flatten a path to a dot delimited string. Args: @@ -28,10 +29,11 @@ def to_path(schema_path: deque[Any]) -> str: Returns: The dot delimited path """ - return ".".join(str(index) for index in schema_path) + queue = schema_path if isinstance(schema_path, deque) else deque(schema_path) + return ".".join(str(index) for index in queue) -def json_path(absolute_path: deque[Any]) -> str: +def json_path(absolute_path: Sequence[Any]) -> str: """Flatten a data path to a dot delimited string. Args: @@ -97,7 +99,7 @@ def validate(schema: str | dict[str, Any], data: dict[str, Any]) -> list[JsonSch if isinstance(schema, str): schema = json.loads(schema) - if isinstance(schema, bool): + if isinstance(schema, (bool, str)): msg = "Unexpected schema data." raise TypeError(msg) validator = validator_for(schema) @@ -129,10 +131,10 @@ def validate(schema: str | dict[str, Any], data: dict[str, Any]) -> list[JsonSch data_path=to_path(validation_error.absolute_path), json_path=json_path(validation_error.absolute_path), schema_path=to_path(validation_error.relative_schema_path), - relative_schema=validation_error.schema, - expected=validation_error.validator_value, - validator=validation_error.validator, - found=validation_error.instance, + relative_schema=str(validation_error.schema), + expected=str(validation_error.validator_value), + validator=str(validation_error.validator), + found=str(validation_error.instance), ) errors.append(error) return errors diff --git a/tests/integration/_common.py b/tests/integration/_common.py index fe9a568e7..4e4729d17 100644 --- a/tests/integration/_common.py +++ b/tests/integration/_common.py @@ -248,7 +248,7 @@ def copytree( try: if symlinks and source_path.is_symlink(): source_link = source_path.readlink() - Path(destination_path).symlink_to(source_link) + source_link.symlink_to(destination_path) elif source_path.is_dir(): copytree( source_path,