From 61273aa2084ada8c48d0f9e511556d3d72eec32c Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Thu, 28 Mar 2024 20:49:34 -0400 Subject: [PATCH] Annotate basic deprecation tests; have mypy scan it - Add type hints to test/deprecation/basic.py. As its module docstring (already) notes, that test module does not contain code where it is specifically important that it be type checked to verify important properties of the code under test. However, other test.deprecation.* modules will, and it is much more convenient to be able to scan the whole directory than the directory except for one file. (Less importantly, for the deprecation tests to be easily readable as a coherent whole, it makes sense that all, not just most, would have annotations.) - Configure mypy in pyproject.toml so it can be run without arguments (mypy errors when run that way unless configured), where the effect is to scan the git/ directory, as was commonly done before, as well as the test/deprecation/ directory. - Change the CI test workflow, as well as tox.ini, to run mypy with no arguments instead of passing `-p git`, so that it will scan both the git package as it had before and the test.deprecation package (due to the new pyproject.toml configuration). - Change the readme to recommend running it that way, too. --- .github/workflows/pythonpackage.yml | 2 +- README.md | 2 +- pyproject.toml | 1 + test/deprecation/test_basic.py | 40 +++++++++++++++++++---------- tox.ini | 2 +- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 7cee0cd64..4c918a92d 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -88,7 +88,7 @@ jobs: - name: Check types with mypy run: | - mypy --python-version=${{ matrix.python-version }} -p git + mypy --python-version=${{ matrix.python-version }} env: MYPY_FORCE_COLOR: "1" TERM: "xterm-256color" # For color: https://github.com/python/mypy/issues/13817 diff --git a/README.md b/README.md index 30af532db..9bedaaae7 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ This includes the linting and autoformatting done by Ruff, as well as some other To typecheck, run: ```sh -mypy -p git +mypy ``` #### CI (and tox) diff --git a/pyproject.toml b/pyproject.toml index 1dc1e6aed..5eac2be09 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ testpaths = "test" # Space separated list of paths from root e.g test tests doc [tool.mypy] python_version = "3.8" +files = ["git/", "test/deprecation/"] disallow_untyped_defs = true no_implicit_optional = true warn_redundant_casts = true diff --git a/test/deprecation/test_basic.py b/test/deprecation/test_basic.py index 459d79268..8ee7e72b1 100644 --- a/test/deprecation/test_basic.py +++ b/test/deprecation/test_basic.py @@ -25,9 +25,21 @@ from git.repo import Repo from git.util import Iterable as _Iterable, IterableObj +# typing ----------------------------------------------------------------- + +from typing import Generator, TYPE_CHECKING + +if TYPE_CHECKING: + from pathlib import Path + + from git.diff import Diff + from git.objects.commit import Commit + +# ------------------------------------------------------------------------ + @contextlib.contextmanager -def _assert_no_deprecation_warning(): +def _assert_no_deprecation_warning() -> Generator[None, None, None]: """Context manager to assert that code does not issue any deprecation warnings.""" with warnings.catch_warnings(): # FIXME: Refine this to filter for deprecation warnings from GitPython. @@ -36,7 +48,7 @@ def _assert_no_deprecation_warning(): @pytest.fixture -def commit(tmp_path): +def commit(tmp_path: "Path") -> Generator["Commit", None, None]: """Fixture to supply a one-commit repo's commit, enough for deprecation tests.""" (tmp_path / "a.txt").write_text("hello\n", encoding="utf-8") repo = Repo.init(tmp_path) @@ -46,67 +58,67 @@ def commit(tmp_path): @pytest.fixture -def diff(commit): +def diff(commit: "Commit") -> Generator["Diff", None, None]: """Fixture to supply a single-file diff.""" (diff,) = commit.diff(NULL_TREE) # Exactly one file in the diff. yield diff -def test_diff_renamed_warns(diff): +def test_diff_renamed_warns(diff: "Diff") -> None: """The deprecated Diff.renamed property issues a deprecation warning.""" with pytest.deprecated_call(): diff.renamed -def test_diff_renamed_file_does_not_warn(diff): +def test_diff_renamed_file_does_not_warn(diff: "Diff") -> None: """The preferred Diff.renamed_file property issues no deprecation warning.""" with _assert_no_deprecation_warning(): diff.renamed_file -def test_commit_trailers_warns(commit): +def test_commit_trailers_warns(commit: "Commit") -> None: """The deprecated Commit.trailers property issues a deprecation warning.""" with pytest.deprecated_call(): commit.trailers -def test_commit_trailers_list_does_not_warn(commit): +def test_commit_trailers_list_does_not_warn(commit: "Commit") -> None: """The nondeprecated Commit.trailers_list property issues no deprecation warning.""" with _assert_no_deprecation_warning(): commit.trailers_list -def test_commit_trailers_dict_does_not_warn(commit): +def test_commit_trailers_dict_does_not_warn(commit: "Commit") -> None: """The nondeprecated Commit.trailers_dict property issues no deprecation warning.""" with _assert_no_deprecation_warning(): commit.trailers_dict -def test_traverse_list_traverse_in_base_class_warns(commit): +def test_traverse_list_traverse_in_base_class_warns(commit: "Commit") -> None: """Traversable.list_traverse's base implementation issues a deprecation warning.""" with pytest.deprecated_call(): Traversable.list_traverse(commit) -def test_traversable_list_traverse_override_does_not_warn(commit): +def test_traversable_list_traverse_override_does_not_warn(commit: "Commit") -> None: """Calling list_traverse on concrete subclasses is not deprecated, does not warn.""" with _assert_no_deprecation_warning(): commit.list_traverse() -def test_traverse_traverse_in_base_class_warns(commit): +def test_traverse_traverse_in_base_class_warns(commit: "Commit") -> None: """Traversable.traverse's base implementation issues a deprecation warning.""" with pytest.deprecated_call(): Traversable.traverse(commit) -def test_traverse_traverse_override_does_not_warn(commit): +def test_traverse_traverse_override_does_not_warn(commit: "Commit") -> None: """Calling traverse on concrete subclasses is not deprecated, does not warn.""" with _assert_no_deprecation_warning(): commit.traverse() -def test_iterable_inheriting_warns(): +def test_iterable_inheriting_warns() -> None: """Subclassing the deprecated git.util.Iterable issues a deprecation warning.""" with pytest.deprecated_call(): @@ -114,7 +126,7 @@ class Derived(_Iterable): pass -def test_iterable_obj_inheriting_does_not_warn(): +def test_iterable_obj_inheriting_does_not_warn() -> None: """Subclassing git.util.IterableObj is not deprecated, does not warn.""" with _assert_no_deprecation_warning(): diff --git a/tox.ini b/tox.ini index 33074a78a..fc62fa587 100644 --- a/tox.ini +++ b/tox.ini @@ -30,7 +30,7 @@ description = Typecheck with mypy base_python = py{39,310,311,312,38,37} set_env = MYPY_FORCE_COLOR = 1 -commands = mypy -p git +commands = mypy ignore_outcome = true [testenv:html]