diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 096228acf9f..b8e7053e1c8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.9" + rev: "v0.7.2" hooks: - id: ruff args: ["--fix"] @@ -12,7 +12,7 @@ repos: - id: end-of-file-fixer - id: check-yaml - repo: https://github.com/adamchainz/blacken-docs - rev: 1.19.0 + rev: 1.19.1 hooks: - id: blacken-docs additional_dependencies: [black==24.1.1] @@ -28,7 +28,7 @@ repos: hooks: - id: python-use-type-annotations - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.2 + rev: v1.13.0 hooks: - id: mypy files: ^(src/|testing/|scripts/) @@ -44,13 +44,13 @@ repos: # on <3.11 - exceptiongroup>=1.0.0rc8 - repo: https://github.com/tox-dev/pyproject-fmt - rev: "2.3.1" + rev: "v2.5.0" hooks: - id: pyproject-fmt # https://pyproject-fmt.readthedocs.io/en/latest/#calculating-max-supported-python-version additional_dependencies: ["tox>=4.9"] - repo: https://github.com/asottile/pyupgrade - rev: v3.18.0 + rev: v3.19.0 hooks: - id: pyupgrade stages: [manual] @@ -61,7 +61,8 @@ repos: entry: pylint language: system types: [python] - args: ["-rn", "-sn", "--fail-on=I"] + args: ["-rn", "-sn", "--fail-on=I", "--enable-all-extentions"] + require_serial: true stages: [manual] - id: rst name: rst diff --git a/pyproject.toml b/pyproject.toml index caeb4bf7f83..ad0bca4374b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ dependencies = [ "exceptiongroup>=1.0.0rc8; python_version<'3.11'", "iniconfig", "packaging", - "pluggy<2,>=1.5", + "pluggy>=1.5,<2", "tomli>=1; python_version<'3.11'", ] optional-dependencies.dev = [ @@ -200,7 +200,9 @@ disable = [ "arguments-renamed", "assigning-non-slot", "attribute-defined-outside-init", + "bad-builtin", "bad-classmethod-argument", + "bad-dunder-name", "bad-mcs-method-argument", "broad-exception-caught", "broad-exception-raised", @@ -209,25 +211,40 @@ disable = [ "comparison-with-callable", "comparison-with-itself", # PLR0124 from ruff "condition-evals-to-constant", + "consider-alternative-union-syntax", + "confusing-consecutive-elif", + "consider-using-any-or-all", + "consider-using-assignment-expr", "consider-using-dict-items", "consider-using-from-import", "consider-using-f-string", "consider-using-in", + "consider-using-namedtuple-or-dataclass", "consider-using-ternary", + "consider-using-tuple", "consider-using-with", "consider-using-from-import", # not activated by default, PLR0402 disabled in ruff + "consider-ternary-expression", "cyclic-import", + "differing-param-doc", + "docstring-first-line-empty", + "deprecated-argument", + "deprecated-attribute", + "deprecated-class", + "deprecated-typing-alias", "disallowed-name", # foo / bar are used often in tests "duplicate-code", "else-if-used", # not activated by default, PLR5501 disabled in ruff "empty-comment", # not activated by default, PLR2044 disabled in ruff "eval-used", + "eq-without-hash", "exec-used", "expression-not-assigned", "fixme", "global-statement", # PLW0603 disabled in ruff "import-error", "import-outside-toplevel", + "import-private-name", "inconsistent-return-statements", "invalid-bool-returned", "invalid-name", @@ -238,8 +255,12 @@ disable = [ "magic-value-comparison", # not activated by default, PLR2004 disabled in ruff "method-hidden", "missing-docstring", + "missing-param-doc", + "missing-raises-doc", "missing-timeout", + "missing-type-doc", "misplaced-bare-raise", # PLE0704 from ruff + "misplaced-comparison-constant", "multiple-statements", # multiple-statements-on-one-line-colon (E701) from ruff "no-else-break", "no-else-continue", @@ -248,6 +269,7 @@ disable = [ "no-member", "no-name-in-module", "no-self-argument", + "no-self-use", "not-an-iterable", "not-callable", "pointless-exception-statement", # https://github.com/pytest-dev/pytest/pull/12379 @@ -260,12 +282,14 @@ disable = [ "redefined-builtin", "redefined-loop-name", # PLW2901 disabled in ruff "redefined-outer-name", + "redefined-variable-type", "reimported", "simplifiable-condition", "simplifiable-if-expression", "singleton-comparison", "superfluous-parens", "super-init-not-called", + "too-complex", "too-few-public-methods", "too-many-ancestors", "too-many-arguments", # disabled in ruff @@ -275,9 +299,11 @@ disable = [ "too-many-lines", "too-many-locals", "too-many-nested-blocks", + "too-many-positional-arguments", "too-many-public-methods", "too-many-return-statements", # disabled in ruff "too-many-statements", # disabled in ruff + "too-many-try-statements", "try-except-raise", "typevar-name-incorrect-variance", # PLC0105 disabled in ruff "unbalanced-tuple-unpacking", @@ -299,10 +325,12 @@ disable = [ "use-dict-literal", "use-implicit-booleaness-not-comparison", "use-implicit-booleaness-not-len", + "use-set-for-membership", "useless-else-on-loop", # PLC0414 disabled in ruff "useless-import-alias", "useless-return", "using-constant-test", + "while-used", "wrong-import-order", # handled by isort / ruff "wrong-import-position", # handled by isort / ruff ] diff --git a/src/_pytest/_io/pprint.py b/src/_pytest/_io/pprint.py index fc29989be0b..7a6433d9128 100644 --- a/src/_pytest/_io/pprint.py +++ b/src/_pytest/_io/pprint.py @@ -111,15 +111,15 @@ def _format( p(self, object, stream, indent, allowance, context, level + 1) context.remove(objid) elif ( - _dataclasses.is_dataclass(object) # type:ignore[unreachable] + _dataclasses.is_dataclass(object) and not isinstance(object, type) - and object.__dataclass_params__.repr + and object.__dataclass_params__.repr # type:ignore[attr-defined] and # Check dataclass has generated repr method. hasattr(object.__repr__, "__wrapped__") and "__create_fn__" in object.__repr__.__wrapped__.__qualname__ ): - context.add(objid) # type:ignore[unreachable] + context.add(objid) self._pprint_dataclass( object, stream, indent, allowance, context, level + 1 ) diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 506c0b3d287..2ac3b6bbc7f 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -15,6 +15,7 @@ from typing import Any from typing import AnyStr from typing import BinaryIO +from typing import cast from typing import Final from typing import final from typing import Generator @@ -177,7 +178,8 @@ def name(self) -> str: def mode(self) -> str: # TextIOWrapper doesn't expose a mode, but at least some of our # tests check it. - return self.buffer.mode.replace("b", "") + assert hasattr(self.buffer, "mode") + return cast(str, self.buffer.mode.replace("b", "")) class CaptureIO(io.TextIOWrapper): @@ -550,7 +552,7 @@ def snap(self) -> bytes: res = self.tmpfile.buffer.read() self.tmpfile.seek(0) self.tmpfile.truncate() - return res + return res # type: ignore[return-value] def writeorg(self, data: bytes) -> None: """Write to original file descriptor.""" diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 3a2cb59a6c1..efe6f489b48 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -74,10 +74,10 @@ def merge_family(left, right) -> None: left.update(result) -families = {} -families["_base"] = {"testcase": ["classname", "name"]} -families["_base_legacy"] = {"testcase": ["file", "line", "url"]} - +families = { # pylint: disable=dict-init-mutate + "_base": {"testcase": ["classname", "name"]}, + "_base_legacy": {"testcase": ["file", "line", "url"]}, +} # xUnit 1.x inherits legacy attributes. families["xunit1"] = families["_base"].copy() merge_family(families["xunit1"], families["_base_legacy"]) diff --git a/testing/test_runner.py b/testing/test_runner.py index 0d9facdcd71..0245438a47d 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -137,8 +137,8 @@ def raiser(exc): ss.teardown_exact(None) mod, func = e.value.exceptions assert isinstance(mod, KeyError) - assert isinstance(func.exceptions[0], TypeError) # type: ignore - assert isinstance(func.exceptions[1], ValueError) # type: ignore + assert isinstance(func.exceptions[0], TypeError) + assert isinstance(func.exceptions[1], ValueError) def test_cached_exception_doesnt_get_longer(self, pytester: Pytester) -> None: """Regression test for #12204 (the "BTW" case)."""