From faba1ef795df53c9ced216166db08df0d3467a21 Mon Sep 17 00:00:00 2001 From: Christophe Combelles Date: Wed, 8 Jul 2026 06:33:49 +0200 Subject: [PATCH 1/3] fix(pyvolca): resolve pre-existing pyright type errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two type-only fixes, no behavior change: - _call's `substitutions` parameter was typed `list[dict]`, but every caller passes `list[SubstitutionLike]` and it forwards straight to `_substitution_body`, which already accepts that. Widen the annotation to match — list invariance made the narrower type reject valid callers. - ConsumersResponse.from_json declared `inner_fetch` then shadowed it with a same-named nested `def`, which pyright flagged as a redeclaration plus an invalid None assignment. Give the closure its own name and capture the narrowed fetch. --- pyvolca/src/volca/client.py | 2 +- pyvolca/src/volca/types.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pyvolca/src/volca/client.py b/pyvolca/src/volca/client.py index b45eed14..62cd9161 100644 --- a/pyvolca/src/volca/client.py +++ b/pyvolca/src/volca/client.py @@ -422,7 +422,7 @@ def _call( self, operation_id: str, *, - substitutions: list[dict] | None = None, + substitutions: list[SubstitutionLike] | None = None, **kwargs: Any, ) -> Any: """Dispatch an OpenAPI operation by ``operationId``. diff --git a/pyvolca/src/volca/types.py b/pyvolca/src/volca/types.py index cea8eb5d..d5276b6e 100644 --- a/pyvolca/src/volca/types.py +++ b/pyvolca/src/volca/types.py @@ -654,8 +654,12 @@ def from_json( if fetch is None: inner_fetch = None else: - def inner_fetch(o: int, l: int | None) -> dict: - return fetch(o, l)["results"] + page_fetch = fetch # narrowed to non-None for the closure below + + def _fetch_results(o: int, l: int | None) -> dict: + return page_fetch(o, l)["results"] + + inner_fetch = _fetch_results return cls( consumers=SearchResults.from_raw( d["results"], parse=ConsumerResult.from_json, fetch=inner_fetch, From fd67ffd5adc35960cb98d43c3f55ba8987853d81 Mon Sep 17 00:00:00 2001 From: Christophe Combelles Date: Wed, 8 Jul 2026 06:33:49 +0200 Subject: [PATCH 2/3] docs: fix diagnostics on sight, don't defer pre-existing ones --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index 3236312a..bfccb653 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -89,6 +89,7 @@ A Python client lives in `pyvolca/` (own `pyproject.toml`); the MUMPS binding in - Simplicity: perfection = nothing left to remove. Avoid over-engineering and cognitive load. - **Pre-1.0 (`v0.y.z`): no backward-compatibility obligation yet** — keep wire formats and APIs clean rather than carrying cruft. Reassess at `v1.0.0`. - Use language servers for fast diagnostics: HLS for Haskell, pyright for the `pyvolca/` Python client. +- Fix a diagnostic the moment you see it, even a pre-existing one you only surfaced in passing — don't defer it to "later" or leave it because it predates your change. A separate small commit keeps it out of your feature's scope. ### Open-source boundary - This engine stands alone — keep deployment/SaaS concerns and any customer- or product-specific names out of code, comments, and PRs. From 4fdd688b91c2d0e20491d2d1e8a45cb0979d8efe Mon Sep 17 00:00:00 2001 From: Christophe Combelles Date: Wed, 8 Jul 2026 06:54:24 +0200 Subject: [PATCH 3/3] ci(pyvolca): gate pyright type-check in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pyright was editor-only, so type regressions never failed CI — which is how the errors fixed in this branch accumulated unnoticed. Add a pinned pyright (dev extra) and a `pyright` step to the pyvolca workflow, scoped to `src/volca` in basic mode via `[tool.pyright]`. Clean at 0 errors. --- .github/workflows/pyvolca.yml | 6 ++++++ pyvolca/pyproject.toml | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pyvolca.yml b/.github/workflows/pyvolca.yml index c363e413..b24859d8 100644 --- a/.github/workflows/pyvolca.yml +++ b/.github/workflows/pyvolca.yml @@ -49,6 +49,12 @@ jobs: - name: Install pyvolca with dev extras run: pip install -e .[dev] + - name: Type-check with pyright + # Pinned pyright (see dev extras) over src/volca; config in + # pyproject.toml [tool.pyright]. Catches type regressions the + # editor LSP would show but pytest never would. + run: pyright + - name: Download engine binary from main's latest build # Pull the linux-amd64 engine artefact from the most recent # successful build.yml run on main. test_drift.py's live_spec diff --git a/pyvolca/pyproject.toml b/pyvolca/pyproject.toml index 0f1c0a05..1f7abb15 100644 --- a/pyvolca/pyproject.toml +++ b/pyvolca/pyproject.toml @@ -16,7 +16,7 @@ classifiers = [ ] [project.optional-dependencies] -dev = ["pytest"] +dev = ["pytest", "pyright==1.1.411"] [project.urls] Documentation = "https://volca.run/docs/guides/pyvolca/" @@ -29,3 +29,8 @@ build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] where = ["src"] + +[tool.pyright] +include = ["src/volca"] +typeCheckingMode = "basic" +pythonVersion = "3.10"