fix(tests): unbreak suite collection and restore the ruff gates - #83
Closed
grandcamel wants to merge 1 commit into
Closed
fix(tests): unbreak suite collection and restore the ruff gates#83grandcamel wants to merge 1 commit into
grandcamel wants to merge 1 commit into
Conversation
Since the pyupgrade sweep (94e0386), test_search_service.py's module import crashes during collection: search_service.py has no future annotations import, so `credentials: HTTPBasicCredentials | None` evaluates eagerly, and under the test's sys.modules stubs that is None | None -> TypeError. The crash lands before the test file's restore block, so the fastapi/numpy/nltk stubs stay installed for the whole pytest session and every later FastAPI-touching test fails with FastAPI=None (95 failed + 9 errors on this checkout; 10 environmental failures after the fix). from __future__ import annotations makes the module's annotations lazy again — no runtime change; the existing test file is itself the regression test. Also restores the LINT/FMT gates, which currently fail on main: - ai_chat/__init__.py: sort __all__ (RUF022) - search/document_processor.py: fold nested if into elif (SIM102) - ruff format over ai_chat/gateway.py and core/function_result.py Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgA3KeCEPMKMJVvroZY1wV
Contributor
|
Superseded by #81, which landed the same fixes: the One line here is genuinely new and not on main — Thanks — the diagnosis was right, it just raced with #81. |
anthmFS
added a commit
that referenced
this pull request
Aug 13, 2026
) * docs(rest)+test(core): true live_transcribe call shape; drop stale ai_sidecar bypass calling.md showed live_transcribe(call_id, action="start", lang="en"), but the generated signature takes action as a keyword-only TypedDict union ({"start": {...}} or the literal "stop") and has no lang/from_lang /to_lang parameters — copying the documented call raises TypeError. The examples now show the real shape, with the start parameters inside the action object where the schema defines them. The sidecar pattern test appended ai_sidecar to the raw document with a comment that the verb was not in the live SWML schema yet. It landed in 4645d48, so the test now uses add_verb_to_section directly — the path the comment promised, and stronger, since the verb goes through schema validation instead of around it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgA3KeCEPMKMJVvroZY1wV (cherry picked from commit 77fc34c) * fix(ai_chat): forward conversation_timeout on the start path prepare() puts conversation_timeout into the start params, but the HTTP dispatch rebuilt the create_conversation call with only id and config_url, silently dropping it. A gateway configured with conversation_timeout=900 told the browser 900 (via effective_timeout) while the service kept its own 3600 default — the page schedules its idle warning around a number the service never enforces. The chat path was unaffected (raw_post streams params verbatim), which kept the drift invisible for conversations opened by a first message. The regression test drives the real HTTP dispatch through the ASGI harness — prepare() was already correct, so a prepare()-level assertion would have passed with the bug in place. Verified red without the fix, green with it; it also pins the auto-create chat path so the two paths cannot drift apart again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgA3KeCEPMKMJVvroZY1wV (cherry picked from commit 5bf93c7) * fix(FunctionResult): emit execute_swml transfer beside the SWML document execute_swml(transfer=True) wrote the flag INSIDE the SWML document — {"SWML": {..., "transfer": "true"}} — where it is not a SWML key, so the document executed but the call never exited the agent. The platform documents transfer as a sibling of the SWML key in the action object, which is exactly the shape the live-proven connect() and swml_transfer() helpers already emit. The action is now {"SWML": <doc>, "transfer": "true"}; transfer=False still omits the key, and the caller's dict is still never mutated. The three tests that pinned the inside placement now pin the sibling placement, one of them asserting shape-parity with connect()'s action so the two paths cannot drift apart again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgA3KeCEPMKMJVvroZY1wV (cherry picked from commit 295c17e) * fix(FunctionResult): tap direction is speak/listen/both, and always emitted The tap() helper disagreed with the SWML schema (and the platform docs) twice over. It accepted and emitted "hear", which is not a tap direction — the verb's enum is speak/listen/both, exactly the set record_call() already uses — so direction="hear" produced SWML the platform rejects; it now raises the existing ValueError instead of silently emitting a dead tap. And its omit-if-default logic assumed the verb's default matches the helper's "both" when the verb actually defaults to "speak", so tap(uri) — documented as tapping both directions — produced a speak-only tap. direction is now always emitted; codec/rtp_ptime omissions stay (their helper defaults match the verb defaults). Note for the port audit: tap.direction's Literal feeds python_signatures.json in porting-sdk as enum<...>, so the oracle needs a regen alongside this change. docs/swaig_reference.md and docs/api_reference.md updated to the real enum (api_reference had a third variant — inbound/outbound plus a G722 codec and sip: URIs that the helper never accepted). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgA3KeCEPMKMJVvroZY1wV (cherry picked from commit 0851a94) * fix: annotate the new gateway test; salvage the search_service import Two small follow-ups to the four fixes cherry-picked above. The `conversation_timeout` test arrived unannotated. mypy has `tests` in scope deliberately ("a new untyped test fails the gate"), so it reds TYPECHECK on main. Annotated; mypy is back to main's exact baseline. `from __future__ import annotations` in search_service.py is the one line worth keeping from #83, which was otherwise superseded by #81. Measured on its own: no change to the mypy count, so it is hygiene rather than a fix. --------- Co-authored-by: grandcamel <jasonkrue@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merge this one first — it unbreaks the test suite and the ruff CI gates for every other open PR.
The suite has been silently ~90-tests-red since the pyupgrade sweep
tests/unit/search/test_search_service.pyreplacesfastapi/numpy/nltk/… insys.moduleswith bare stubs at module scope, importssearch_service, then restores everything. Since 94e0386 (chore(lint): enable ruff pyupgrade) rewroteOptional[X]toX | None, that import dies half-way:search_service.pyhas nofrom __future__ import annotations, so the method annotationcredentials: HTTPBasicCredentials | Noneis evaluated eagerly at class-definition time — and with the stub'sHTTPBasicCredentials = Nonethat'sNone | None→TypeError.The crash happens during collection, before the restore block runs, so the stubs stay installed for the entire pytest session. Every later test that touches FastAPI (
ai_chat,web,auth_handler,web_mixin,security/webhook) inherits afastapimodule whoseFastAPIisNone. On this checkout that's 95 failed + 9 errors; with this two-line fix the same environment reports 10 failed / 5139 passed (the 10 are unrelated environment issues: 9 ×test_examplesstdout-log pollution, 1 × sentence-transformers/torch unavailable on Intel macOS). Runtime also drops ~10 min → ~2.5 min.Fix:
from __future__ import annotationsinsearch_service.py, making its annotations lazy — the module now imports cleanly under the test's stubs, the restore block runs, and no state leaks. No runtime behavior change. The existing test file is itself the regression test: without the future-import its collection crashes.Restore the ruff gates
run-ci.sh's LINT/FMT gates currently fail on main (recent commits landed without them):ai_chat/__init__.py— RUF022,__all__not sortedsearch/document_processor.py— SIM102, nestedifcollapsed into theelifcondition (no behavior change)ruff formatoverai_chat/gateway.pyandcore/function_result.py(formatting only)After this PR:
ruff check signalwireandruff format --check signalwireboth pass.🤖 Generated with Claude Code
https://claude.ai/code/session_01MgA3KeCEPMKMJVvroZY1wV