From 556340114f36b17279b4bd3965532271d94f42ee Mon Sep 17 00:00:00 2001 From: Panadestein Date: Tue, 6 Oct 2026 15:19:32 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20=F0=9F=94=A7=20type-check=20tests=20an?= =?UTF-8?q?d=20bump=20ty=20monthly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finishes #28 on top of #37: ty now checks tests/ as well as src/, and a scheduled update-ty.yml bumps the ty pin in pyproject.toml and prek.toml together, opening the PR as a draft when the new version reports diagnostics. The one finding in tests/ was real: chi_out was annotated as int although NumPy integers are accepted on purpose. The public signatures now take int | np.integer, and validate_chi_out returns a plain int. Closes #28 Assisted-by: pi:claude-opus-5.5 --- .github/workflows/update-ty.yml | 103 ++++++++++++++++++++++++++++++++ AGENTS.md | 2 +- CONTRIBUTING.md | 2 +- pyproject.toml | 2 +- src/src_method/_validation.py | 6 +- src/src_method/apply.py | 3 +- src/src_method/compress.py | 3 +- src/src_method/stack.py | 5 +- 8 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/update-ty.yml diff --git a/.github/workflows/update-ty.yml b/.github/workflows/update-ty.yml new file mode 100644 index 0000000..a813965 --- /dev/null +++ b/.github/workflows/update-ty.yml @@ -0,0 +1,103 @@ +name: Update ty Version Monthly + +on: + schedule: + # Run on the 1st of every month at 00:00 UTC + - cron: '0 0 1 * *' + workflow_dispatch: # Allow manual triggering + +jobs: + update-ty: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Get latest ty version + run: | + LATEST_VERSION=$(curl -s https://pypi.org/pypi/ty/json | jq -r '.info.version') + echo "TY_VERSION=$LATEST_VERSION" >> $GITHUB_ENV + echo "Latest ty version: $LATEST_VERSION" + + if grep -q '"ty==' pyproject.toml; then + CURRENT_VERSION=$(grep '"ty==' pyproject.toml | sed -E 's/.*ty==([0-9]+\.[0-9]+\.[0-9]+).*/\1/') + echo "CURRENT_VERSION=$CURRENT_VERSION" >> $GITHUB_ENV + echo "Current ty version: $CURRENT_VERSION" + + if [ "$LATEST_VERSION" = "$CURRENT_VERSION" ]; then + echo "Already using the latest version of ty. No updates needed." + echo "NEEDS_UPDATE=false" >> $GITHUB_ENV + else + echo "NEEDS_UPDATE=true" >> $GITHUB_ENV + fi + else + echo "No ty version found in pyproject.toml" + echo "NEEDS_UPDATE=true" >> $GITHUB_ENV + fi + + - name: Update ty version in pyproject.toml + if: env.NEEDS_UPDATE == 'true' + run: | + sed -i -E 's/"ty==([0-9]+\.[0-9]+\.[0-9]+)"/"ty==${{ env.TY_VERSION }}"/' pyproject.toml + + - name: Update ty version in prek.toml + if: env.NEEDS_UPDATE == 'true' + run: | + sed -i -E '/repo = "https:\/\/github.com\/astral-sh\/ty-pre-commit"/,/^rev = / s/^rev = "v[0-9]+\.[0-9]+\.[0-9]+"/rev = "v${{ env.TY_VERSION }}"/' prek.toml + + - name: Install the latest version of uv + if: env.NEEDS_UPDATE == 'true' + uses: astral-sh/setup-uv@v7 + + - name: Update the lockfile + if: env.NEEDS_UPDATE == 'true' + run: | + uv lock + + - name: Run ty on the project + # ty is pre-1.0 and new releases often add diagnostics; a failure opens + # the PR as a draft instead of aborting the update. + if: env.NEEDS_UPDATE == 'true' + run: | + set +e + uv run --group dev ty check + if [ $? -ne 0 ]; then + echo "TY_CHECK_FAILED=true" >> $GITHUB_ENV + else + echo "TY_CHECK_FAILED=false" >> $GITHUB_ENV + fi + + - name: Create Pull Request + if: env.NEEDS_UPDATE == 'true' + uses: peter-evans/create-pull-request@v8 + with: + token: ${{ secrets.GITHUB_TOKEN }} + # open in draft mode if ty check failed + draft: ${{ env.TY_CHECK_FAILED }} + commit-message: "chore(deps-dev): update ty from ${{ env.CURRENT_VERSION }} to ${{ env.TY_VERSION }}" + title: "chore(deps-dev): update ty from ${{ env.CURRENT_VERSION }} to ${{ env.TY_VERSION }}" + body: | + ## ty Version Update + + This PR updates the ty version from ${{ env.CURRENT_VERSION }} to ${{ env.TY_VERSION }}. + + Changes: + - Updated version in `pyproject.toml` + - Updated version in `prek.toml` + - Regenerated `uv.lock` + + ${{ env.TY_CHECK_FAILED == 'true' && '⚠️ **WARNING**: `ty check` reports new diagnostics with this version. A maintainer should fix them before merging.' || '`ty check` passes with this version.' }} + + This PR was created automatically by a GitHub Actions workflow. + branch: chore-deps-update-ty-${{ env.TY_VERSION }} + delete-branch: true + labels: | + dependencies + add-paths: | + pyproject.toml + prek.toml + uv.lock diff --git a/AGENTS.md b/AGENTS.md index 3fd0018..44a8ceb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,7 +64,7 @@ uv run prek install --prepare-hooks uv run pytest -m "not slow" # fast suite uv run pytest # everything uv run ruff check src/ tests/ -uv run ty check src/ +uv run ty check # src/ and tests/, per pyproject.toml uv run mkdocs serve ``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2daf540..ee689cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,7 +43,7 @@ All of these must pass before a pull request can be merged; ```bash uv run ruff check src/ tests/ # lint uv run ruff format --check src/ tests/ -uv run ty check src/ # type check +uv run ty check # type check src/ and tests/ uv run pytest -m "not slow" # fast test suite uv run pytest # full suite, including slow tests ``` diff --git a/pyproject.toml b/pyproject.toml index 317aae2..dbd789c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -278,4 +278,4 @@ python-version = "3.11" allowed-unresolved-imports = ["cupy"] [tool.ty.src] -include = ["src/src_method"] +include = ["src/src_method", "tests"] diff --git a/src/src_method/_validation.py b/src/src_method/_validation.py index 5fbf893..ed8cbbb 100644 --- a/src/src_method/_validation.py +++ b/src/src_method/_validation.py @@ -19,7 +19,7 @@ __all__ = ["validate_chi_out", "validate_cutoff", "validate_open_boundary"] -def validate_chi_out(chi_out: int) -> None: +def validate_chi_out(chi_out: object) -> int: """Reject a non-integer or non-positive output bond dimension. Any `numbers.Integral` is accepted, so NumPy integers pass; `bool` does not. @@ -27,6 +27,9 @@ def validate_chi_out(chi_out: int) -> None: Args: chi_out: The requested output bond dimension. + Returns: + ``chi_out`` as a plain `int`. + Raises: TypeError: If `chi_out` is not an integer. ValueError: If `chi_out` is not positive. @@ -37,6 +40,7 @@ def validate_chi_out(chi_out: int) -> None: if chi_out < 1: msg = f"chi_out must be positive, got {chi_out!r}." raise ValueError(msg) + return int(chi_out) def validate_cutoff(cutoff: float) -> None: diff --git a/src/src_method/apply.py b/src/src_method/apply.py index 534c00d..7ea086e 100644 --- a/src/src_method/apply.py +++ b/src/src_method/apply.py @@ -16,13 +16,14 @@ if TYPE_CHECKING: from collections.abc import Sequence + import numpy as np from numpy.typing import DTypeLike, NDArray def apply( left_tensor: Sequence[NDArray], right_tensor: Sequence[NDArray], - chi_out: int, + chi_out: int | np.integer, *, cutoff: float = 0.0, dtype: DTypeLike | None = None, diff --git a/src/src_method/compress.py b/src/src_method/compress.py index bdff465..ef37d84 100644 --- a/src/src_method/compress.py +++ b/src/src_method/compress.py @@ -15,12 +15,13 @@ if TYPE_CHECKING: from collections.abc import Sequence + import numpy as np from numpy.typing import DTypeLike, NDArray def compress( tensor: Sequence[NDArray], - chi_out: int, + chi_out: int | np.integer, *, cutoff: float = 0.0, dtype: DTypeLike | None = None, diff --git a/src/src_method/stack.py b/src/src_method/stack.py index a7f7ace..9b32baa 100644 --- a/src/src_method/stack.py +++ b/src/src_method/stack.py @@ -23,6 +23,7 @@ if TYPE_CHECKING: from collections.abc import Sequence + import numpy as np from numpy.typing import DTypeLike, NDArray logger = logging.getLogger(__name__) @@ -35,7 +36,7 @@ def src( *trains: Sequence[NDArray], - chi_out: int, + chi_out: int | np.integer, cutoff: float = 0.0, dtype: DTypeLike | None = None, seed: int | None = None, @@ -95,7 +96,7 @@ def src( not recognised. ImportError: If ``device="gpu"`` but cupy is not installed. """ - validate_chi_out(chi_out) + chi_out = validate_chi_out(chi_out) validate_cutoff(cutoff) xp = get_xp(device) prng = default_rng(seed)