1818from re import Pattern
1919
2020from .process import AbortSignal
21- from .stream import stream_data
21+ from .stream import complete_stream , start_stream
2222from .utils import convert_to_camel_case , convert_to_snake_case
2323
2424if TYPE_CHECKING :
@@ -317,13 +317,13 @@ async def write_file(
317317 mode: Set the file permission mode.
318318 """
319319 if isinstance (data , bytes ):
320- # Stream bytes as a single chunk
321- content_stream_id = await stream_data (self ._rpc , iter ([data ]))
320+ streamable = iter ([data ])
322321 else :
323- # Stream data from iterable/file object
324- content_stream_id = await stream_data (self ._rpc , data )
322+ streamable = data
325323
326- params : dict [str , Any ] = {"path" : path , "contentStreamId" : content_stream_id }
324+ stream_id , writer = await start_stream (self ._rpc )
325+
326+ params : dict [str , Any ] = {"path" : path , "contentStreamId" : stream_id }
327327 options : dict [str , Any ] = {}
328328 if create is not None :
329329 options ["create" ] = create
@@ -335,7 +335,20 @@ async def write_file(
335335 options ["mode" ] = mode
336336 if options :
337337 params ["options" ] = convert_to_camel_case (options )
338- await self ._rpc .call ("writeFile" , params )
338+
339+ # Send data concurrently with the RPC call to avoid deadlock:
340+ # the server waits for stream data before responding to writeFile.
341+ async def _send () -> None :
342+ try :
343+ await complete_stream (writer , streamable )
344+ except Exception as e :
345+ await writer .error (str (e ))
346+
347+ task = self ._rpc ._loop .create_task (_send ())
348+ try :
349+ await self ._rpc .call ("writeFile" , params )
350+ finally :
351+ await task
339352
340353 async def read_text_file (
341354 self ,
0 commit comments