fix(ci): stop pytest collection failing on the anyio 4.15 BlockingPortal deprecation - #732
Conversation
…ortal deprecation anyio 4.15.0 (2026-09-02) deprecated the anyio.abc.BlockingPortal alias. Every released starlette (<= 1.6.0) still imports it at module scope in starlette/testclient.py, so with filterwarnings = error the DeprecationWarning is raised from 'from fastapi.testclient import TestClient' and seven server test modules fail at collection on 3.11, 3.12 and 3.13. The last green run on main (2026-08-23) resolved anyio 4.14.2. starlette merged the fix upstream (Kludex/starlette#3498) but has not shipped it, and pinning anyio<4.15 would either constrain wheel users for a test-only warning or live in an extra CI never installs. Ignore exactly that one message from exactly that one module instead; it becomes a no-op once a fixed starlette is released.
test_api_memory_lessons_lists_active_lessons hard-coded valid_until to 2026-08-30 and asserted memory_status == active, but the endpoint evaluates expiry against the wall clock, so the test turned red on its own on 2026-08-30. Derive the expiry from now (+90 days) and assert the serialised value against the same datetime.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Greptile SummaryThis update restores server-test collection by narrowly ignoring Starlette’s deprecated AnyIO Confidence Score: 5/5Safe to merge; the updated test configuration and active-lesson endpoint behavior both performed as intended. No issues were found. The warning exception allowed server-test collection while unrelated deprecations still failed, and the endpoint preserved a generated future expiry while reporting the lesson as active. Files Needing Attention: None.
What T-Rex did
Reviews (1): Last reviewed commit: "fix(tests): keep the active-lesson fixtu..." | Re-trigger Greptile |
Why the pytest matrix went red
Every
pytest (3.11 / 3.12 / 3.13)job on #731 fails at collection withraised from
starlette/testclient.py:53(
_PortalFactoryType = Callable[[], AbstractContextManager[anyio.abc.BlockingPortal]])the moment a test module does
from fastapi.testclient import TestClient. Sevenserver test modules (
test_batteries_serve,test_server,test_server_api_contract,test_server_code_intelligence,test_server_static_ui,test_server_usage,test_streaming_endpoints) never collect, so the whole session is interrupted.What moved, and when. The workflow installs
pytest,fastapi,httpxandhttpx2unpinned viauv run --with. The last green run onmain(2026-08-23)resolved anyio 4.14.2. anyio 4.15.0 shipped on 2026-09-02 (4.15.1 on 2026-09-05)
and turned
anyio.abc.BlockingPortalinto a lazily-resolved deprecated alias thatwarns on access. starlette 1.6.0 (2026-08-08, still the latest release, pulled by
fastapi 0.141.1) reads that alias at import time. With
filterwarnings = ["error"]in
pyproject.toml, the warning is an import-time exception. This is not a runnerproblem: #731 only changes
runs-on, and the same failure reproduces locally withthe workflow's exact
uv runline againstmain. Nothing in this repo's own codetouches anyio.
Fix
pyproject.toml: onefilterwarningsentry that ignores exactly thatmessage, of exactly that category, from exactly the
starlette.testclientmodule. This is a third-party warning with no released fix: starlette merged
Use anyio.from_thread.BlockingPortal in TestClient Kludex/starlette#3498 (switches to
anyio.from_thread.BlockingPortal) but hasnot cut a release that contains it. Once a fixed starlette ships the entry is a
no-op and can be dropped; the comment says so.
Why not pin
anyio<4.15instead: independenciesit would constrain everyalfred-oswheel user for a test-only warning; in thedevextra it wouldnever be installed, because CI runs
uv run --with ...without--extra dev;as a uv constraint it would not help a plain pip venv. The scoped ignore works
for every install path and expires on its own.
tests/test_server.py: the collection failure was masking a second,unrelated drift.
test_api_memory_lessons_lists_active_lessonshard-codedvalid_until=2026-08-30and assertedmemory_status == "active", but theendpoint evaluates expiry against the wall clock, so the test turned red by
itself on 2026-08-30 on all three Pythons. The expiry is now derived from
now + 90 daysand the serialised value is asserted against that same datetime.Verification
uv run --python X --with pytest --with fastapi --with httpx --with httpx2 pytest tests/on 3.11, 3.12 and 3.13: identical 7 collection errors before the change.
--with 'anyio<4.15'alone also clears collection, confirming which package drifted.A full 3.13 run of the suite showed no other failure hiding behind the collection
error (the only extra red was three release-gate tests that fail solely under a
local git config with commit signing forced on, and pass with it neutralised).
ruff check/ruff format --check(0.15.22) clean;bin/scrub-check.shclean.Follow-up for #731
#731 needs no change. Once this lands, rebase or re-run its CI
(
gh run rerun <run-id> --failed) and the pytest matrix should go green there too.