diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29d0b94..aae2e24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,13 @@ jobs: type-check: runs-on: ubuntu-latest needs: lint + strategy: + fail-fast: false + matrix: + target: + - landmarkdiff/ + - scripts/ + - benchmarks/ steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 @@ -37,8 +44,8 @@ jobs: cache: pip - name: Install dependencies run: pip install -e ".[dev]" - - name: Type check - run: mypy landmarkdiff/ --ignore-missing-imports + - name: Type check ${{ matrix.target }} + run: mypy ${{ matrix.target }} pre-commit: runs-on: ubuntu-latest needs: lint diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec5e97b..89486e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,6 +28,7 @@ repos: additional_dependencies: [types-Pillow, types-PyYAML, types-requests] exclude: '\.ipynb$' args: [ + --explicit-package-bases, --ignore-missing-imports, --config-file=pyproject.toml, --exclude, 'scripts/benchmark_inference\.py', diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 0000000..46ae392 --- /dev/null +++ b/benchmarks/__init__.py @@ -0,0 +1 @@ +"""Benchmarks package for LandmarkDiff performance testing.""" diff --git a/landmarkdiff/api_client_async.py b/landmarkdiff/api_client_async.py index 307dd20..15b0284 100644 --- a/landmarkdiff/api_client_async.py +++ b/landmarkdiff/api_client_async.py @@ -22,7 +22,7 @@ async def main(): import base64 import logging from pathlib import Path -from typing import Any +from typing import Any, cast import cv2 import numpy as np @@ -91,7 +91,7 @@ async def _handle_response(self, resp: Any) -> dict[str, Any]: if resp.status >= 400: text = await resp.text() raise LandmarkDiffAPIError(f"Server returned {resp.status}: {text[:200]}") - return await resp.json() + return cast(dict[str, Any], await resp.json()) # ------------------------------------------------------------------ # API methods @@ -124,7 +124,7 @@ async def procedures(self) -> list[str]: try: async with session.get(f"{self.base_url}/procedures") as resp: data = await self._handle_response(resp) - return data.get("procedures", []) + return cast(list[str], data.get("procedures", [])) except LandmarkDiffAPIError: raise except Exception as e: diff --git a/landmarkdiff/comparison.py b/landmarkdiff/comparison.py index c1ead45..1b28cdb 100644 --- a/landmarkdiff/comparison.py +++ b/landmarkdiff/comparison.py @@ -7,6 +7,7 @@ from __future__ import annotations import logging +from typing import cast import cv2 import numpy as np @@ -47,7 +48,7 @@ def create_slider_composite( if line_width > 0 and 0 < split_x < w: cv2.line(result, (split_x, 0), (split_x, h - 1), line_color, line_width) - return result + return cast(np.ndarray, result) def create_side_by_side( @@ -101,7 +102,7 @@ def create_side_by_side( cv2.LINE_AA, ) - return canvas + return cast(np.ndarray, canvas) def create_difference_heatmap( @@ -127,7 +128,7 @@ def create_difference_heatmap( diff = cv2.absdiff(original, pred) gray_diff = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) amplified = np.clip(gray_diff.astype(np.float32) * amplify, 0, 255).astype(np.uint8) - return cv2.applyColorMap(amplified, colormap) + return cast(np.ndarray, cv2.applyColorMap(amplified, colormap)) def create_checkerboard_blend( @@ -166,4 +167,4 @@ def create_checkerboard_blend( mask_3ch = np.stack([mask] * 3, axis=-1) result = original.astype(np.float32) * mask_3ch + pred.astype(np.float32) * (1.0 - mask_3ch) - return np.clip(result, 0, 255).astype(np.uint8) + return cast(np.ndarray, np.clip(result, 0, 255).astype(np.uint8)) diff --git a/landmarkdiff/planning.py b/landmarkdiff/planning.py index dfa23e9..72abeaf 100644 --- a/landmarkdiff/planning.py +++ b/landmarkdiff/planning.py @@ -8,6 +8,7 @@ from __future__ import annotations from dataclasses import dataclass +from typing import cast import cv2 import numpy as np @@ -214,4 +215,4 @@ def visualize_planning( cv2.LINE_AA, ) - return canvas + return cast(np.ndarray, canvas) diff --git a/pyproject.toml b/pyproject.toml index 9379a57..b18666f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -192,16 +192,19 @@ ignore = [ [tool.mypy] python_version = "3.10" -warn_return_any = false +warn_return_any = true warn_unused_configs = true -disallow_untyped_defs = false -check_untyped_defs = false +disallow_untyped_defs = true +check_untyped_defs = true explicit_package_bases = true ignore_missing_imports = true +strict_optional = true +warn_redundant_casts = true +warn_unused_ignores = true exclude = [ - "scripts/batch_inference.py", - "scripts/benchmark_inference.py", "examples/*.ipynb", + "tests/*.py", + "examples/", ] [[tool.mypy.overrides]] @@ -246,3 +249,11 @@ ignore_errors = true [[tool.mypy.overrides]] module = ["scripts.*"] ignore_errors = true + +[[tool.mypy.overrides]] +module = ["tests.*"] +ignore_errors = true + +[[tool.mypy.overrides]] +module = ["examples.*"] +ignore_errors = true diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..2bf8e08 --- /dev/null +++ b/scripts/__init__.py @@ -0,0 +1 @@ +"""Scripts package for LandmarkDiff utilities and experiments."""