Skip to content

Commit 9dedb40

Browse files
committed
Heal 3.11 coverage tracing in the new dispatcher tests
The new post-close DirectDispatcher test asserts after running_pair's cancelled task-group join, and several of the new jsonrpc_dispatcher race tests have a 1-tick join fast path - both shapes hit python/cpython#106749 on 3.11 (coro.throw() drops the outer-frame 'call' trace events and desyncs CTracer until the next normal resume, roaming onto unrelated tests on the same xdist worker). Add the established resync_tracer() heal at each new cancel site.
1 parent a27bca7 commit 9dedb40

2 files changed

Lines changed: 10 additions & 0 deletions

File tree

tests/shared/test_dispatcher.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import anyio
1414
import pytest
1515

16+
from mcp.shared._compat import resync_tracer
1617
from mcp.shared.direct_dispatcher import DirectDispatcher, create_direct_dispatcher_pair
1718
from mcp.shared.dispatcher import DispatchContext, Dispatcher, OnNotify, OnRequest, Outbound
1819
from mcp.shared.exceptions import MCPError
@@ -80,6 +81,7 @@ async def running_pair(
8081
finally:
8182
tg.cancel_scope.cancel()
8283
finally:
84+
await resync_tracer()
8385
close()
8486

8587

tests/shared/test_jsonrpc_dispatcher.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from mcp import Client
1616
from mcp.server import Server, ServerRequestContext
17+
from mcp.shared._compat import resync_tracer
1718
from mcp.shared._context_streams import ContextReceiveStream, ContextSendStream
1819
from mcp.shared.dispatcher import CallOptions, DispatchContext
1920
from mcp.shared.exceptions import MCPError, NoBackChannelError
@@ -605,6 +606,7 @@ async def caller() -> None:
605606
await client.notify("notifications/marker", None)
606607
tg.cancel_scope.cancel()
607608
finally:
609+
await resync_tracer()
608610
s2c_send.close()
609611
s2c_recv.close()
610612
assert scopes[0].cancelled_caught
@@ -667,6 +669,7 @@ async def marker_after_caller_unwinds() -> None:
667669
assert marker.message == JSONRPCNotification(jsonrpc="2.0", method="notifications/marker")
668670
tg.cancel_scope.cancel()
669671
finally:
672+
await resync_tracer()
670673
for s in (c2s_send, c2s_recv, s2c_send, s2c_recv):
671674
s.close()
672675
assert scopes[0].cancelled_caught
@@ -706,6 +709,7 @@ async def caller() -> None:
706709
assert first.message == JSONRPCNotification(jsonrpc="2.0", method="notifications/marker")
707710
tg.cancel_scope.cancel()
708711
finally:
712+
await resync_tracer()
709713
for s in (c2s_send, c2s_recv, s2c_send, s2c_recv):
710714
s.close()
711715
assert scopes[0].cancelled_caught
@@ -867,6 +871,7 @@ async def test_transport_write_timeout_propagates_raw_when_no_request_timeout_is
867871
assert transport.attempts == 1
868872
tg.cancel_scope.cancel()
869873
finally:
874+
await resync_tracer()
870875
s2c_send.close()
871876
s2c_recv.close()
872877

@@ -1072,6 +1077,7 @@ async def run_server() -> None:
10721077
stream_closed = True
10731078
assert stream_closed
10741079
finally:
1080+
await resync_tracer()
10751081
for s in (read_send, read_recv, write_send, write_recv):
10761082
s.close()
10771083
assert outer.cancelled_caught
@@ -1156,6 +1162,7 @@ async def test_notify_after_connection_close_is_dropped_with_debug_log(caplog: p
11561162
with pytest.raises(anyio.EndOfStream):
11571163
c2s_recv.receive_nowait() # nothing reached the wire
11581164
finally:
1165+
await resync_tracer()
11591166
for s in (c2s_send, c2s_recv, s2c_send, s2c_recv):
11601167
s.close()
11611168

@@ -1177,6 +1184,7 @@ async def test_notify_on_torn_down_transport_is_dropped_with_debug_log(caplog: p
11771184
assert "dropped notifications/roots/list_changed: write stream closed" in caplog.text
11781185
tg.cancel_scope.cancel()
11791186
finally:
1187+
await resync_tracer()
11801188
for s in (c2s_send, c2s_recv, s2c_send, s2c_recv):
11811189
s.close()
11821190

0 commit comments

Comments
 (0)