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/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 ea2e7a9..5dcf6a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -279,4 +279,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)