From fe942894c90fe815d9030a6d53a8726a89434bef Mon Sep 17 00:00:00 2001 From: Thor Whalen <1906276+thorwhalen@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:28:12 +0100 Subject: [PATCH] Fix red CI: install the dev extra, and let package doctests run CI has been red on the default branch since the Phase 1 backend commit. Root cause (Validation (3.12) / "Run Tests"): ERROR collecting tests/test_ingest.py tests/test_ingest.py:4: from fastapi.testclient import TestClient starlette/testclient.py:41: RuntimeError: The starlette.testclient module requires the httpx2 package to be installed. The wads reusable workflow installs `-e .` with only the extras named in `[tool.wads.ci.install].extras`, which defaults to none. That key was unset, so the `dev` extra -- which is where the HTTP client the FastAPI TestClient needs is declared -- was never installed, and every test module importing `fastapi.testclient` failed at collection (exit code 2). Changes: - `[tool.wads.ci.install] extras = "dev"` -- the actual fix; CI now installs `.[dev]` instead of bare `.`. - Add `httpx2` beside `httpx` in the `dev` extra. starlette >= 1 imports `httpx2` first and only falls back to `httpx` with a deprecation warning; starlette < 1 knows `httpx` alone. Declaring both makes the suite collect on either resolution -- they are distinct top-level modules. - Widen `testpaths` to `["tests", "heed"]`. wads CI runs `pytest --doctest-modules` with no path argument, so collection is driven entirely by `testpaths`; with `["tests"]` the package's own doctests never ran. The `heed/__init__.py` usage doctest now executes (and passes). - Correct the stale comment claiming the PyPI name `heed` is reserved for this repo. It is not -- it is taken by an unrelated project, so a first release needs a different distribution name. Publishing stays disabled. Verified in clean uv venvs on Python 3.10 and 3.12 with the exact CI command (`pytest --doctest-modules -o doctest_optionflags=... --ignore=examples --ignore=scrap -v --tb=short`): 2 collection errors before, 10 passed after. `ruff check heed` and `ruff format` are clean. No package code changed. Claude-Session: https://claude.ai/code/session_01VipiLaG4xy7WctqY9w2475 --- pyproject.toml | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d78c467..df7e00d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,10 +42,18 @@ github = ["ghapi>=1.0"] enlace = ["enlace>=0.1.0"] # Expose the feedback queue to a coding agent (e.g. Claude Code) over MCP. mcp = ["py2mcp>=0.1.0"] -dev = ["pytest", "httpx", "pytest-asyncio"] +# Test/dev tooling. `fastapi.testclient` delegates to `starlette.testclient`, +# which needs an HTTP client at import time: starlette >=1 prefers `httpx2` and +# only falls back to `httpx` with a deprecation warning, while starlette <1 +# knows `httpx` alone. Both are declared so the suite collects on either +# resolution; they are distinct top-level modules and coexist fine. +dev = ["pytest", "httpx", "httpx2", "pytest-asyncio"] [tool.pytest.ini_options] -testpaths = ["tests"] +# wads CI runs `pytest --doctest-modules` with NO path argument, so collection is +# driven entirely by `testpaths`. The package dir must be listed here or none of +# its doctests ever run. +testpaths = ["tests", "heed"] [tool.ruff] line-length = 88 @@ -58,9 +66,16 @@ ignore = ["D203"] [tool.wads.ci] installer = "uv" +[tool.wads.ci.install] +# CI installs only the core dependencies unless extras are named here. The test +# suite needs the `dev` extra (its HTTP client in particular), so opt in. +extras = "dev" + [tool.wads.ci.publish] -# Design phase: do NOT auto-publish to PyPI on main pushes. Flip to true for the -# first real release (the PyPI name `heed` is reserved by this repo's intent). +# Design phase: do NOT auto-publish to PyPI on main pushes. +# NOTE: the PyPI name `heed` is NOT available -- it is taken by an unrelated +# project. A first release therefore needs a different distribution name (the +# import package can stay `heed`). See the repo issues for that decision. enabled = false [tool.wads.ci.testing]