diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6a81b6022..dad38dbc9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.28.2 + rev: 0.28.3 hooks: - id: check-github-workflows args: [ "--verbose" ] @@ -20,12 +20,11 @@ repos: - id: tox-ini-fmt args: ["-p", "fix"] - repo: https://github.com/tox-dev/pyproject-fmt - rev: "1.8.0" + rev: "2.0.4" hooks: - id: pyproject-fmt - additional_dependencies: ["tox>=4.14.2"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.2" + rev: "v0.4.4" hooks: - id: ruff-format - id: ruff diff --git a/pyproject.toml b/pyproject.toml index 5e9b104a8..dc3ff02ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,9 @@ maintainers = [ { name = "Jürgen Gmach", email = "juergen.gmach@googlemail.com" }, { name = "Oliver Bestwalter", email = "oliver@bestwalter.de" }, ] -authors = [{ name = "Bernát Gábor", email = "gaborjbernat@gmail.com" }] +authors = [ + { name = "Bernát Gábor", email = "gaborjbernat@gmail.com" }, +] requires-python = ">=3.8" classifiers = [ "Development Status :: 5 - Production/Stable", @@ -51,13 +53,13 @@ dependencies = [ "chardet>=5.2", "colorama>=0.4.6", "filelock>=3.13.1", - 'importlib-metadata>=7.0.1; python_version < "3.8"', + "importlib-metadata>=7.0.1; python_version<'3.8'", "packaging>=23.2", "platformdirs>=4.1", "pluggy>=1.3", "pyproject-api>=1.6.1", - 'tomli>=2.0.1; python_version < "3.11"', - 'typing-extensions>=4.9; python_version < "3.8"', + "tomli>=2.0.1; python_version<'3.11'", + "typing-extensions>=4.9; python_version<'3.8'", "virtualenv>=20.25", ] optional-dependencies.docs = [ @@ -86,7 +88,7 @@ optional-dependencies.testing = [ "pytest-mock>=3.12", "pytest-xdist>=3.5", "re-assert>=1.1", - 'time-machine>=2.13; implementation_name != "pypy"', + "time-machine>=2.13; implementation_name!='pypy'", "wheel>=0.42", ] urls.Documentation = "https://tox.wiki" @@ -97,16 +99,29 @@ urls.Tracker = "https://github.com/tox-dev/tox/issues" scripts.tox = "tox.run:run" [tool.hatch] -build.dev-mode-dirs = ["src"] +build.dev-mode-dirs = [ + "src", +] build.hooks.vcs.version-file = "src/tox/version.py" -build.targets.sdist.include = ["/src", "/tests", "/tox.ini"] +build.targets.sdist.include = [ + "/src", + "/tests", + "/tox.ini", +] version.source = "vcs" [tool.ruff] line-length = 120 target-version = "py38" -lint.isort = { known-first-party = ["tox", "tests"], required-imports = ["from __future__ import annotations"] } -lint.select = ["ALL"] +lint.isort = { known-first-party = [ + "tox", + "tests", +], required-imports = [ + "from __future__ import annotations", +] } +lint.select = [ + "ALL", +] lint.ignore = [ "CPY", # No copyright header "INP001", # no implicit namespaces here @@ -145,7 +160,9 @@ ignore-words = "ignore-words.txt" count = true [tool.pytest.ini_options] -testpaths = ["tests"] +testpaths = [ + "tests", +] addopts = "--tb=auto -ra --showlocals --no-success-flaky-report" [tool.coverage] @@ -160,9 +177,15 @@ paths.source = [ "*\\src", ] report.fail_under = 88 -report.omit = ["src/tox/config/cli/for_docs.py", "tests/execute/local_subprocess/bad_process.py", "tests/type_check/*"] +report.omit = [ + "src/tox/config/cli/for_docs.py", + "tests/execute/local_subprocess/bad_process.py", + "tests/type_check/*", +] run.parallel = true -run.plugins = ["covdefaults"] +run.plugins = [ + "covdefaults", +] [tool.towncrier] name = "tox" diff --git a/src/tox/config/cli/parse.py b/src/tox/config/cli/parse.py index 0412e11b0..b62d3fb0a 100644 --- a/src/tox/config/cli/parse.py +++ b/src/tox/config/cli/parse.py @@ -2,6 +2,7 @@ from __future__ import annotations +import locale import os from contextlib import redirect_stderr from pathlib import Path @@ -46,7 +47,9 @@ def _get_base(args: Sequence[str]) -> tuple[int, ToxHandler, Source]: tox_parser = ToxParser.base() parsed = Parsed() try: - with Path(os.devnull).open("w") as file_handler, redirect_stderr(file_handler): + with Path(os.devnull).open( + "w", encoding=locale.getpreferredencoding(do_setlocale=False) + ) as file_handler, redirect_stderr(file_handler): tox_parser.parse_known_args(args, namespace=parsed) except SystemExit: ... # ignore parse errors, such as -va raises ignored explicit argument 'a' diff --git a/src/tox/config/cli/parser.py b/src/tox/config/cli/parser.py index 707c7fc8a..c8d13f797 100644 --- a/src/tox/config/cli/parser.py +++ b/src/tox/config/cli/parser.py @@ -62,7 +62,7 @@ def get_type(action: Action) -> type[Any]: loc = locals() loc["Literal"] = Literal as_literal = f"Literal[{', '.join(repr(i) for i in action.choices)}]" - of_type = eval(as_literal, globals(), loc) # noqa: PGH001, S307 + of_type = eval(as_literal, globals(), loc) # noqa: S307 elif action.default is not None: of_type = type(action.default) elif isinstance(action, argparse._StoreConstAction) and action.const is not None: # noqa: SLF001 diff --git a/src/tox/journal/__init__.py b/src/tox/journal/__init__.py index 5c976ef9e..4f054afd6 100644 --- a/src/tox/journal/__init__.py +++ b/src/tox/journal/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +import locale from pathlib import Path from .env import EnvJournal @@ -12,7 +13,7 @@ def write_journal(path: Path | None, journal: Journal) -> None: if path is None: return - with Path(path).open("w") as file_handler: + with Path(path).open("w", encoding=locale.getpreferredencoding(do_setlocale=False)) as file_handler: json.dump(journal.content, file_handler, indent=2, ensure_ascii=False) diff --git a/src/tox/provision.py b/src/tox/provision.py index 840eabb2b..9e1e2bf8c 100644 --- a/src/tox/provision.py +++ b/src/tox/provision.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +import locale import logging import sys from importlib.metadata import PackageNotFoundError, distribution @@ -116,7 +117,9 @@ def add_tox_requires_min_version(reqs: list[Requirement]) -> list[Requirement]: "minversion": min_version[1] if len(min_version) >= 2 else None, # noqa: PLR2004 "requires": [str(i) for i in requires], } - Path(no_provision).write_text(json.dumps(requires_dict, indent=4)) + Path(no_provision).write_text( + json.dumps(requires_dict, indent=4), encoding=locale.getpreferredencoding(do_setlocale=False) + ) raise HandledError(msg) logging.warning("will run in automatically provisioned tox, host %s %s", sys.executable, miss_msg) diff --git a/src/tox/run.py b/src/tox/run.py index 11df6c010..5c048e8b7 100644 --- a/src/tox/run.py +++ b/src/tox/run.py @@ -18,7 +18,7 @@ def run(args: Sequence[str] | None = None) -> None: try: with ToxHandler.patch_thread(): result = main(sys.argv[1:] if args is None else args) - except Exception as exception: # noqa: BLE001 + except Exception as exception: if isinstance(exception, HandledError): logging.error("%s| %s", type(exception).__name__, str(exception)) # noqa: TRY400 result = -2 diff --git a/src/tox/session/cmd/run/common.py b/src/tox/session/cmd/run/common.py index 07731dab6..1ef0a934e 100644 --- a/src/tox/session/cmd/run/common.py +++ b/src/tox/session/cmd/run/common.py @@ -229,7 +229,7 @@ def update_spinner(self, result: ToxEnvRunResult, success: bool) -> None: # noq done(result.name) -def _queue_and_wait( # noqa: C901, PLR0913, PLR0915 +def _queue_and_wait( # noqa: C901, PLR0913, PLR0915, PLR0912 state: State, to_run_list: list[str], results: list[ToxEnvRunResult], diff --git a/src/tox/session/cmd/run/single.py b/src/tox/session/cmd/run/single.py index ccb29e6ae..a742dc86a 100644 --- a/src/tox/session/cmd/run/single.py +++ b/src/tox/session/cmd/run/single.py @@ -52,7 +52,7 @@ def _evaluate(tox_env: RunToxEnv, no_test: bool) -> tuple[bool, int, list[Outcom skipped = True except ToxBackendFailed as exception: LOGGER.error("%s", exception) # noqa: TRY400 - raise SystemExit(exception.code) # noqa: B904, TRY200 + raise SystemExit(exception.code) # noqa: B904 except Fail as exception: LOGGER.error("failed with %s", exception) # noqa: TRY400 code = 1