@@ -197,24 +197,30 @@ def _make_write_pipe_transport(self, pipe, protocol, waiter=None,
197197 async def _make_subprocess_transport (self , protocol , args , shell ,
198198 stdin , stdout , stderr , bufsize ,
199199 extra = None , ** kwargs ):
200- watcher = self ._watcher
201- waiter = self .create_future ()
202- transp = _UnixSubprocessTransport (self , protocol , args , shell ,
203- stdin , stdout , stderr , bufsize ,
204- waiter = waiter , extra = extra ,
205- ** kwargs )
206- watcher .add_child_handler (transp .get_pid (),
207- self ._child_watcher_callback , transp )
208- try :
209- await waiter
210- except (SystemExit , KeyboardInterrupt ):
211- raise
212- except BaseException :
213- transp .close ()
214- await transp ._wait ()
215- raise
200+ async def shielded ():
201+ # See https://github.com/python/cpython/issues/103847
202+ # This code needs to be shielded to prevent cancellation
203+ # as _UnixSubprocessTransport doesn't handle it properly.
204+ watcher = self ._watcher
205+ waiter = self .create_future ()
206+ transp = _UnixSubprocessTransport (self , protocol , args , shell ,
207+ stdin , stdout , stderr , bufsize ,
208+ waiter = waiter , extra = extra ,
209+ ** kwargs )
210+ watcher .add_child_handler (transp .get_pid (),
211+ self ._child_watcher_callback , transp )
212+ try :
213+ await waiter
214+ except (SystemExit , KeyboardInterrupt ):
215+ raise
216+ except BaseException :
217+ transp .close ()
218+ await transp ._wait ()
219+ raise
220+
221+ return transp
216222
217- return transp
223+ return await tasks . shield ( shielded ())
218224
219225 def _child_watcher_callback (self , pid , returncode , transp ):
220226 self .call_soon_threadsafe (transp ._process_exited , returncode )
0 commit comments