Skip to content

test(mcp): drive MCP tool calls through asyncio.run - #1087

Closed
doublewhy wants to merge 1 commit into
devfrom
test-mcp-event-loop
Closed

test(mcp): drive MCP tool calls through asyncio.run#1087
doublewhy wants to merge 1 commit into
devfrom
test-mcp-event-loop

Conversation

@doublewhy

@doublewhy doublewhy commented Aug 12, 2026

Copy link
Copy Markdown

Plain-language summary

  • Context: The MCP tests need to run asynchronous tool calls on every supported Python version.
  • Problem: They relied on an implicitly created event loop, behavior removed in Python 3.14, so otherwise valid MCP tests failed before exercising the server.
  • Fix: Run each asynchronous test call through asyncio.run(), which creates and closes the loop explicitly.

Related issues

Closes #1117

Required by the broader interpreter qualification in #1097.


What breaks

tests/test_mcp_server.py fails entirely — all 85 tests — on Python 3.14. It passes today only because CI pins 3.12, where the same call is merely deprecated.

Concretely

The module drives its async MCP calls from synchronous test code like this:

return asyncio.get_event_loop().run_until_complete(_async_call(server, tool, args or {}))

Calling asyncio.get_event_loop() with no running loop has emitted a DeprecationWarning since 3.12. In 3.14 it raises:

RuntimeError: There is no current event loop in thread 'MainThread'

So the file is one interpreter bump away from taking out the whole MCP test module, and it currently adds a DeprecationWarning to every run of the suite.

I hit this for real: running the full gate on a Linux host where uv selected 3.14 rather than the pinned 3.12, ~20 of these failed before I noticed the interpreter mismatch.

The fix

asyncio.run(...), which is the supported way to drive a coroutine from sync code. Two call sites. Tests only — no package code changes.

How I know

I reproduced 3.14's behaviour on 3.12 by promoting the warning to an error, since it is the same call that hard-fails there:

pytest tests/test_mcp_server.py -W error::DeprecationWarning
  • before: DeprecationWarning: There is no current event loop errors the module
  • after: 85 passed

Full hermetic suite green. The suite's warning count drops by one, because this was the source.

🤖 Generated with Claude Code

`asyncio.get_event_loop()` outside a running loop has warned since 3.12
and raises `RuntimeError: There is no current event loop` on 3.14, so the
whole module fails there — 20+ tests — while only emitting a
DeprecationWarning on the interpreters CI currently pins. `asyncio.run`
is the supported spelling for driving a coroutine from sync test code.

Verified by running the module under `-W error::DeprecationWarning`,
which reproduces the 3.14 failure: the previous spelling errors out,
this one passes all 85 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Brad-Edwards

Copy link
Copy Markdown
Collaborator

Please note in the comments or body which issue this PR closes. If no issue exists, please create one and link it.

Thank you!

@doublewhy

Copy link
Copy Markdown
Author

Linked the focused Python 3.14 MCP test issue in the PR body: this PR closes #1117. Thank you.

@doublewhy

Copy link
Copy Markdown
Author

Superseded by #1134, which closes #1117 and #1097. The successor retains the asyncio.run() MCP fix and verifies it across the complete supported interpreter/build/install matrix.

@doublewhy doublewhy closed this Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants