@@ -1078,6 +1078,27 @@ def _kill_process(self, method, *args):
10781078 getattr (p , method )(* args )
10791079 return p
10801080
1081+ def _kill_dead_process (self , method , * args ):
1082+ # Do not inherit file handles from the parent.
1083+ # It should fix failures on some platforms.
1084+ p = subprocess .Popen ([sys .executable , "-c" , """if 1:
1085+ import sys, time
1086+ sys.stdout.write('x\\ n')
1087+ sys.stdout.flush()
1088+ """ ],
1089+ close_fds = True ,
1090+ stdin = subprocess .PIPE ,
1091+ stdout = subprocess .PIPE ,
1092+ stderr = subprocess .PIPE )
1093+ # Wait for the interpreter to be completely initialized before
1094+ # sending any signal.
1095+ p .stdout .read (1 )
1096+ # The process should end after this
1097+ time .sleep (1 )
1098+ # This shouldn't raise even though the child is now dead
1099+ getattr (p , method )(* args )
1100+ p .communicate ()
1101+
10811102 def test_send_signal (self ):
10821103 p = self ._kill_process ('send_signal' , signal .SIGINT )
10831104 _ , stderr = p .communicate ()
@@ -1096,6 +1117,18 @@ def test_terminate(self):
10961117 self .assertStderrEqual (stderr , b'' )
10971118 self .assertEqual (p .wait (), - signal .SIGTERM )
10981119
1120+ def test_send_signal_dead (self ):
1121+ # Sending a signal to a dead process
1122+ self ._kill_dead_process ('send_signal' , signal .SIGINT )
1123+
1124+ def test_kill_dead (self ):
1125+ # Killing a dead process
1126+ self ._kill_dead_process ('kill' )
1127+
1128+ def test_terminate_dead (self ):
1129+ # Terminating a dead process
1130+ self ._kill_dead_process ('terminate' )
1131+
10991132 def check_close_std_fds (self , fds ):
11001133 # Issue #9905: test that subprocess pipes still work properly with
11011134 # some standard fds closed
@@ -1662,6 +1695,31 @@ def _kill_process(self, method, *args):
16621695 returncode = p .wait ()
16631696 self .assertNotEqual (returncode , 0 )
16641697
1698+ def _kill_dead_process (self , method , * args ):
1699+ p = subprocess .Popen ([sys .executable , "-c" , """if 1:
1700+ import sys, time
1701+ sys.stdout.write('x\\ n')
1702+ sys.stdout.flush()
1703+ sys.exit(42)
1704+ """ ],
1705+ stdin = subprocess .PIPE ,
1706+ stdout = subprocess .PIPE ,
1707+ stderr = subprocess .PIPE )
1708+ self .addCleanup (p .stdout .close )
1709+ self .addCleanup (p .stderr .close )
1710+ self .addCleanup (p .stdin .close )
1711+ # Wait for the interpreter to be completely initialized before
1712+ # sending any signal.
1713+ p .stdout .read (1 )
1714+ # The process should end after this
1715+ time .sleep (1 )
1716+ # This shouldn't raise even though the child is now dead
1717+ getattr (p , method )(* args )
1718+ _ , stderr = p .communicate ()
1719+ self .assertStderrEqual (stderr , b'' )
1720+ rc = p .wait ()
1721+ self .assertEqual (rc , 42 )
1722+
16651723 def test_send_signal (self ):
16661724 self ._kill_process ('send_signal' , signal .SIGTERM )
16671725
@@ -1671,6 +1729,15 @@ def test_kill(self):
16711729 def test_terminate (self ):
16721730 self ._kill_process ('terminate' )
16731731
1732+ def test_send_signal_dead (self ):
1733+ self ._kill_dead_process ('send_signal' , signal .SIGTERM )
1734+
1735+ def test_kill_dead (self ):
1736+ self ._kill_dead_process ('kill' )
1737+
1738+ def test_terminate_dead (self ):
1739+ self ._kill_dead_process ('terminate' )
1740+
16741741
16751742# The module says:
16761743# "NB This only works (and is only relevant) for UNIX."
0 commit comments