From f967a957aa5cd7d15236ff28a58d5ee1daafc5b9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 18:34:32 +0000 Subject: [PATCH 1/2] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/tox-dev/pyproject-fmt: v2.11.1 → v2.26.0](https://github.com/tox-dev/pyproject-fmt/compare/v2.11.1...v2.26.0) - [github.com/astral-sh/ruff-pre-commit: v0.14.10 → v0.16.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.10...v0.16.0) - [github.com/codespell-project/codespell: v2.4.1 → v2.4.3](https://github.com/codespell-project/codespell/compare/v2.4.1...v2.4.3) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6afe3e6..005e4b6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,17 +7,17 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/tox-dev/pyproject-fmt - rev: "v2.11.1" + rev: "v2.26.0" hooks: - id: pyproject-fmt - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.10 + rev: v0.16.0 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 + rev: v2.4.3 hooks: - id: codespell additional_dependencies: ["tomli"] From 80c5d422b5849d622e06cd668be2edc92ced5ab9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 18:34:47 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyproject.toml | 70 ++++++++++++++++------------------- pytest_test_utils/__init__.py | 4 +- pytest_test_utils/matchers.py | 12 +++--- pytest_test_utils/tmp_dir.pyi | 14 ++++--- tests.py | 2 +- 5 files changed, 48 insertions(+), 54 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e081ce5..e994b24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,8 +41,8 @@ urls.Issues = "https://github.com/iterative/pytest-test-utils/issues" urls.Source = "https://github.com/iterative/pytest-test-utils" entry-points.pytest11.pytest_test_utils = "pytest_test_utils.pytest_plugin" -[tool.setuptools.package-data] -pytest_test_utils = [ +[tool.setuptools] +package-data.pytest_test_utils = [ "py.typed", ] @@ -50,7 +50,6 @@ pytest_test_utils = [ [tool.ruff] show-fixes = true - output-format = "full" lint.extend-select = [ "B", @@ -66,53 +65,46 @@ lint.ignore = [ [tool.codespell] ignore-words-list = "cachable" -[tool.pytest.ini_options] -testpaths = [ +[tool.mypy] +files = [ + "pytest_test_utils", + "tests.py", +] +check_untyped_defs = true +warn_redundant_casts = true +warn_no_return = true +warn_unreachable = true +strict = true +show_error_context = true +# Error output +show_column_numbers = true +pretty = true +show_traceback = true +overrides = [ { module = [ + "tests", +], strict_equality = false } ] +show_error_codes = true + +[tool.pytest] +ini_options.testpaths = [ "tests.py", ] -[tool.coverage.run] -branch = true -source = [ +[tool.coverage] +run.branch = true +run.source = [ "pytest_test_utils", ] - -[tool.coverage.paths] -source = [ +paths.source = [ "dvc", ] - -[tool.coverage.report] -exclude_lines = [ +report.exclude_lines = [ + "@overload", "if __name__ == .__main__.:", "if TYPE_CHECKING:", "if typing.TYPE_CHECKING:", - "@overload", "pragma: no cover", "raise AssertionError", "raise NotImplementedError", ] -show_missing = true - -[tool.mypy] -# Error output -show_column_numbers = true -show_error_codes = true -show_error_context = true -show_traceback = true -pretty = true -check_untyped_defs = true -strict = true -warn_no_return = true -warn_redundant_casts = true -warn_unreachable = true -files = [ - "pytest_test_utils", - "tests.py", -] - -[[tool.mypy.overrides]] -module = [ - "tests", -] -strict_equality = false +report.show_missing = true diff --git a/pytest_test_utils/__init__.py b/pytest_test_utils/__init__.py index ab3e8f2..8132c61 100644 --- a/pytest_test_utils/__init__.py +++ b/pytest_test_utils/__init__.py @@ -3,8 +3,8 @@ from .tmp_dir_factory import TempDirFactory __all__ = [ + "TempDirFactory", + "TmpDir", "matchers", "waiters", - "TmpDir", - "TempDirFactory", ] diff --git a/pytest_test_utils/matchers.py b/pytest_test_utils/matchers.py index bf567a2..f296a94 100644 --- a/pytest_test_utils/matchers.py +++ b/pytest_test_utils/matchers.py @@ -29,7 +29,7 @@ def __repr__(self) -> str: flags_repr = f", {flags}" if flags else "" return f"regex(r'{self._regex.pattern!s}'{flags_repr})" - def __eq__(self, other: Any) -> bool: + def __eq__(self, other: object) -> bool: assert isinstance(other, (str, bytes)) return bool(self._regex.search(other)) # type: ignore[arg-type] @@ -42,7 +42,7 @@ class any: def __repr__(self) -> str: return "any" - def __eq__(self, other: Any) -> bool: + def __eq__(self, other: object) -> bool: return True @@ -62,7 +62,7 @@ def __len__(self) -> int: return len(self.d) def __repr__(self) -> str: - inner = ", ".join(f"{k}={repr(v)}" for k, v in self.d.items()) + inner = ", ".join(f"{k}={v!r}" for k, v in self.d.items()) return f"M.dict({inner})" def __eq__(self, other: object) -> bool: @@ -93,10 +93,10 @@ def __init__(self, **attribs: Any) -> None: self.attribs = attribs def __repr__(self) -> str: - inner = ", ".join(f"{k}={repr(v)}" for k, v in self.attribs.items()) + inner = ", ".join(f"{k}={v!r}" for k, v in self.attribs.items()) return f"attrs({inner})" - def __eq__(self, other: Any) -> bool: + def __eq__(self, other: object) -> bool: # Unforturnately this doesn't work with classes with slots # self.__class__ = other.__class__ return all(getattr(other, name) == v for name, v in self.attribs.items()) @@ -125,7 +125,7 @@ def __repr__(self) -> str: inner = self.expected_type.__name__ return f"{self.__class__.__name__}({inner})" - def __eq__(self, other: Any) -> bool: + def __eq__(self, other: object) -> bool: return isinstance(other, self.expected_type) diff --git a/pytest_test_utils/tmp_dir.pyi b/pytest_test_utils/tmp_dir.pyi index 918970f..6d400b9 100644 --- a/pytest_test_utils/tmp_dir.pyi +++ b/pytest_test_utils/tmp_dir.pyi @@ -2,14 +2,16 @@ import os from pathlib import Path from typing import Any, ContextManager, Dict, List, TypeVar, Union, overload +from typing_extensions import TypeAlias + T = TypeVar("T", str, bytes) -Text = Union[str, bytes] -AnyPath = Union[T, os.PathLike[T]] -AnyStruct = Dict[AnyPath[T], Union[Text, Dict[AnyPath[T], Any]]] -StrStruct = AnyStruct[str] -BytesStruct = AnyStruct[bytes] +Text: TypeAlias = Union[str, bytes] +AnyPath: TypeAlias = Union[T, os.PathLike[T]] +AnyStruct: TypeAlias = Dict[AnyPath[T], Union[Text, Dict[AnyPath[T], Any]]] +StrStruct: TypeAlias = AnyStruct[str] +BytesStruct: TypeAlias = AnyStruct[bytes] -CatStruct = Union[str, Dict[str, Union[str, Dict[str, Any]]]] +CatStruct: TypeAlias = Union[str, Dict[str, Union[str, Dict[str, Any]]]] class TmpDir(Path): @overload diff --git a/tests.py b/tests.py index 0b544c2..1e78bf2 100644 --- a/tests.py +++ b/tests.py @@ -101,7 +101,7 @@ def test_matcher_repr(matcher: Type[Matcher]) -> None: assert repr(matcher.any) == "any" assert repr(matcher.attrs(foo="foo")) == "attrs(foo='foo')" assert repr(matcher.any_of(3, 4)) == "any_of(3, 4)" - assert repr(matcher.dict(foo="foo", **{"n": 123})) == "M.dict(foo='foo', n=123)" + assert repr(matcher.dict(foo="foo", n=123)) == "M.dict(foo='foo', n=123)" assert repr(matcher.instance_of(str)) == "instance_of(str)" assert repr(matcher.instance_of((str, bytes))) == "instance_of((str, bytes))" assert repr(matcher.unordered("foo", "bar")) == "unordered('foo', 'bar')"