@@ -989,6 +989,27 @@ def _kill_process(self, method, *args):
989989 getattr (p , method )(* args )
990990 return p
991991
992+ def _kill_dead_process (self , method , * args ):
993+ # Do not inherit file handles from the parent.
994+ # It should fix failures on some platforms.
995+ p = subprocess .Popen ([sys .executable , "-c" , """if 1:
996+ import sys, time
997+ sys.stdout.write('x\\ n')
998+ sys.stdout.flush()
999+ """ ],
1000+ close_fds = True ,
1001+ stdin = subprocess .PIPE ,
1002+ stdout = subprocess .PIPE ,
1003+ stderr = subprocess .PIPE )
1004+ # Wait for the interpreter to be completely initialized before
1005+ # sending any signal.
1006+ p .stdout .read (1 )
1007+ # The process should end after this
1008+ time .sleep (1 )
1009+ # This shouldn't raise even though the child is now dead
1010+ getattr (p , method )(* args )
1011+ p .communicate ()
1012+
9921013 def test_send_signal (self ):
9931014 p = self ._kill_process ('send_signal' , signal .SIGINT )
9941015 _ , stderr = p .communicate ()
@@ -1007,6 +1028,18 @@ def test_terminate(self):
10071028 self .assertStderrEqual (stderr , b'' )
10081029 self .assertEqual (p .wait (), - signal .SIGTERM )
10091030
1031+ def test_send_signal_dead (self ):
1032+ # Sending a signal to a dead process
1033+ self ._kill_dead_process ('send_signal' , signal .SIGINT )
1034+
1035+ def test_kill_dead (self ):
1036+ # Killing a dead process
1037+ self ._kill_dead_process ('kill' )
1038+
1039+ def test_terminate_dead (self ):
1040+ # Terminating a dead process
1041+ self ._kill_dead_process ('terminate' )
1042+
10101043 def check_close_std_fds (self , fds ):
10111044 # Issue #9905: test that subprocess pipes still work properly with
10121045 # some standard fds closed
@@ -1568,6 +1601,31 @@ def _kill_process(self, method, *args):
15681601 returncode = p .wait ()
15691602 self .assertNotEqual (returncode , 0 )
15701603
1604+ def _kill_dead_process (self , method , * args ):
1605+ p = subprocess .Popen ([sys .executable , "-c" , """if 1:
1606+ import sys, time
1607+ sys.stdout.write('x\\ n')
1608+ sys.stdout.flush()
1609+ sys.exit(42)
1610+ """ ],
1611+ stdin = subprocess .PIPE ,
1612+ stdout = subprocess .PIPE ,
1613+ stderr = subprocess .PIPE )
1614+ self .addCleanup (p .stdout .close )
1615+ self .addCleanup (p .stderr .close )
1616+ self .addCleanup (p .stdin .close )
1617+ # Wait for the interpreter to be completely initialized before
1618+ # sending any signal.
1619+ p .stdout .read (1 )
1620+ # The process should end after this
1621+ time .sleep (1 )
1622+ # This shouldn't raise even though the child is now dead
1623+ getattr (p , method )(* args )
1624+ _ , stderr = p .communicate ()
1625+ self .assertStderrEqual (stderr , b'' )
1626+ rc = p .wait ()
1627+ self .assertEqual (rc , 42 )
1628+
15711629 def test_send_signal (self ):
15721630 self ._kill_process ('send_signal' , signal .SIGTERM )
15731631
@@ -1577,6 +1635,15 @@ def test_kill(self):
15771635 def test_terminate (self ):
15781636 self ._kill_process ('terminate' )
15791637
1638+ def test_send_signal_dead (self ):
1639+ self ._kill_dead_process ('send_signal' , signal .SIGTERM )
1640+
1641+ def test_kill_dead (self ):
1642+ self ._kill_dead_process ('kill' )
1643+
1644+ def test_terminate_dead (self ):
1645+ self ._kill_dead_process ('terminate' )
1646+
15801647
15811648# The module says:
15821649# "NB This only works (and is only relevant) for UNIX."
0 commit comments