From 2bff4d742cf4311bcb024593480b6501b9e98d2c Mon Sep 17 00:00:00 2001 From: scttfrdmn <3011922+scttfrdmn@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:53:57 -0700 Subject: [PATCH] fix: pin ruff <0.16, and actually run it in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ruff` was declared in the dev extra but no workflow ever invoked it, so it enforced nothing. Two problems fixed together: 1. Pin `ruff>=0.5,<0.16`. ruff 0.16 moved a large set of opinionated rules into its DEFAULT set; unpinned it reported 76 findings here, 73 of them annotation-style suggestions (UP045/UP037/UP006) the rest of the suite doesn't enforce. Same cap as the four workflow adapters. 2. Add a `lint` job running `ruff check .`, so the pin guards a check that runs. Single Python version — lint results don't vary across the matrix. The 3 real findings under the pin were all in examples/ and are fixed: - marimo_example.py computed `state_color` then never used it, so the status table rendered the state uncolored; now applied as intended. - script_example.py had an f-string with no placeholders. - jupyter_example.ipynb E402 is inherent to notebooks (each cell is its own top level) → excluded per-file, not worked around in the example. Verified: ruff resolves to 0.15.22, `ruff check .` passes, 19 tests pass, both edited examples parse, and the notebook is still linted for everything except E402. No change to the shipped `spore` package. --- .github/workflows/test-python-build.yaml | 14 ++++++++++++++ CHANGELOG.md | 19 +++++++++++++++++++ examples/marimo_example.py | 2 +- examples/script_example.py | 2 +- pyproject.toml | 17 ++++++++++++++++- 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-python-build.yaml b/.github/workflows/test-python-build.yaml index f92211a..d8a53ae 100644 --- a/.github/workflows/test-python-build.yaml +++ b/.github/workflows/test-python-build.yaml @@ -36,3 +36,17 @@ jobs: run: pip install -e ".[dev]" - name: Test run: pytest tests/ -v --tb=short + + lint: + # `ruff` was a declared dev dependency that CI never invoked, so it enforced + # nothing. Run it on one version (lint results don't vary across the matrix). + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install + run: pip install -e ".[dev]" + - name: Lint (ruff) + run: ruff check . diff --git a/CHANGELOG.md b/CHANGELOG.md index bbbd0ff..33a90f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,25 @@ Release tags use the `python-vX.Y.Z` prefix. ## [Unreleased] +### Fixed +- **`ruff` was a declared dev dependency that CI never ran, so it enforced + nothing — it's now pinned `<0.16` and actually invoked.** ruff 0.16 moved a + large set of opinionated rules into its **default** set; unpinned, `ruff check .` + reported 76 findings here, of which 73 were annotation-style suggestions + (`UP045`/`UP037`/`UP006`) that the rest of the suite doesn't enforce either. With + the cap, 3 real findings remained, all in `examples/` and all fixed: + - `marimo_example.py` computed a `state_color` for the instance state and then + never used it — the status table rendered the state uncolored. Now applied, as + originally intended. + - `script_example.py` had an f-string with no placeholders. + - `jupyter_example.ipynb` tripped `E402` (import not at top of cell), which is + inherent to notebooks — every cell is its own top level — so it's excluded per + file rather than worked around in the example. + A `lint` job now runs `ruff check .` on 3.12 (lint results don't vary across the + test matrix), so the pin protects a check that actually executes. Matches the cap + on the four workflow adapters. + No change to the shipped `spore` package — examples, tooling and CI only. + ## [0.1.5] - 2026-07-10 ### Added diff --git a/examples/marimo_example.py b/examples/marimo_example.py index 1b99789..faec6a8 100644 --- a/examples/marimo_example.py +++ b/examples/marimo_example.py @@ -135,7 +135,7 @@ def _(inst_input, mo): | Field | Value | |-------|-------| | Type | {inst.instance_type} | - | State | **{inst.state}** | + | State | **{inst.state}** | | Region | {inst.region} | | IP | {inst.public_ip or "—"} | | TTL | {inst.ttl or "—"} | diff --git a/examples/script_example.py b/examples/script_example.py index f219db6..e12592f 100644 --- a/examples/script_example.py +++ b/examples/script_example.py @@ -55,7 +55,7 @@ def extend_if_needed(name: str, min_ttl_hours: float = 1.0): # For demo: just show how to extend if inst.state == "running": inst.extend("2h") - print(f" → Extended TTL by 2h") + print(" → Extended TTL by 2h") if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index a016297..1324e21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,14 @@ dependencies = [ [project.optional-dependencies] jupyter = ["ipywidgets>=8.0", "IPython>=8.0"] -dev = ["pytest>=7", "pytest-asyncio", "black", "ruff"] +# ruff is capped below 0.16: that release moved a large set of opinionated rules +# (UP045, UP037, UP006, BLE, TRY, C408, B017, …) into the DEFAULT rule set, so an +# unpinned `ruff check .` changes what it enforces whenever ruff publishes — here +# it took the count from 3 real findings to 76, the rest being annotation-style +# suggestions. Same cap as the workflow adapters (airflow-spawn, cwl-spawn, +# miniwdl-spawn, snakemake-executor-plugin-spawn). Raising it is a deliberate +# change: pick the rules to adopt via an explicit `[tool.ruff.lint] select`. +dev = ["pytest>=7", "pytest-asyncio", "black", "ruff>=0.5,<0.16"] [project.urls] Homepage = "https://spore.host" @@ -42,3 +49,11 @@ Issues = "https://github.com/spore-host/spore-host/issues" [tool.hatch.build.targets.wheel] packages = ["spore"] + +[tool.ruff] +line-length = 100 + +[tool.ruff.lint.per-file-ignores] +# Notebook cells legitimately import mid-document (each cell is its own top +# level), so E402 "import not at top of cell" is noise for an example notebook. +"examples/*.ipynb" = ["E402"]