File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -86,6 +86,8 @@ def __init__(
8686 self ._closed = False
8787 self ._disconnected = False
8888 self ._sender = (sender_factory or self ._default_sender_factory )(self ._writer , self ._tasks )
89+ self ._observers : list [StreamObserver ] = list (observers or [])
90+ self ._receive_timeout = receive_timeout
8991 if listening :
9092 self ._recv_task = self ._tasks .create (
9193 self ._receive_loop (),
@@ -103,8 +105,6 @@ def __init__(
103105 self ._run_notification ,
104106 )
105107 self ._dispatcher .start ()
106- self ._observers : list [StreamObserver ] = list (observers or [])
107- self ._receive_timeout = receive_timeout
108108
109109 async def close (self ) -> None :
110110 """Stop the receive loop and cancel any in-flight handler tasks."""
Original file line number Diff line number Diff line change @@ -676,3 +676,32 @@ async def test_spawn_agent_process_roundtrip(tmp_path):
676676 assert test_client .notifications
677677
678678 assert process .returncode is not None
679+
680+
681+ @pytest .mark .asyncio
682+ async def test_connection_init_under_eager_task_factory (server ):
683+ eager_task_factory = getattr (asyncio , "eager_task_factory" , None )
684+ if eager_task_factory is None :
685+ pytest .skip ("asyncio.eager_task_factory requires Python 3.12+" )
686+
687+ # Regression: under asyncio.eager_task_factory the receive loop runs synchronously
688+ # up to its first await inside Connection.__init__, so every attribute it reads
689+ # (e.g. _receive_timeout) must be assigned before _tasks.create(_receive_loop()).
690+ loop = asyncio .get_running_loop ()
691+ previous_factory = loop .get_task_factory ()
692+ loop .set_task_factory (eager_task_factory )
693+ try :
694+ conn = Connection (
695+ lambda method , params , is_notification : None ,
696+ server .client_writer ,
697+ server .client_reader ,
698+ receive_timeout = 0.5 ,
699+ )
700+ finally :
701+ loop .set_task_factory (previous_factory )
702+
703+ assert conn ._receive_timeout == 0.5
704+ # Let the loop tick once so any deferred receive-task crash would land.
705+ await asyncio .sleep (0 )
706+ assert conn ._disconnected is False
707+ await conn .close ()
You can’t perform that action at this time.
0 commit comments