mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Refactor test_preexec_errpipe to not create an uncollectable reference cycle.
This commit is contained in:
		
							parent
							
								
									19e568d254
								
							
						
					
					
						commit
						e27faac45f
					
				
					 1 changed files with 18 additions and 19 deletions
				
			
		| 
						 | 
					@ -1035,22 +1035,15 @@ def raise_it():
 | 
				
			||||||
            self.fail("Exception raised by preexec_fn did not make it "
 | 
					            self.fail("Exception raised by preexec_fn did not make it "
 | 
				
			||||||
                      "to the parent process.")
 | 
					                      "to the parent process.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @unittest.skipIf(not os.path.exists("/dev/zero"), "/dev/zero required.")
 | 
					    class _TestExecuteChildPopen(subprocess.Popen):
 | 
				
			||||||
    def test_preexec_errpipe_does_not_double_close_pipes(self):
 | 
					        """Used to test behavior at the end of _execute_child."""
 | 
				
			||||||
        """Issue16140: Don't double close pipes on preexec error."""
 | 
					        def __init__(self, testcase, *args, **kwargs):
 | 
				
			||||||
        class SafeConstructorPopen(subprocess.Popen):
 | 
					            self._testcase = testcase
 | 
				
			||||||
            def __init__(self):
 | 
					 | 
				
			||||||
                pass  # Do nothing so we can modify the instance for testing.
 | 
					 | 
				
			||||||
            def RealPopen(self, *args, **kwargs):
 | 
					 | 
				
			||||||
            subprocess.Popen.__init__(self, *args, **kwargs)
 | 
					            subprocess.Popen.__init__(self, *args, **kwargs)
 | 
				
			||||||
        def raise_it():
 | 
					 | 
				
			||||||
            raise RuntimeError("force the _execute_child() errpipe_data path.")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        p = SafeConstructorPopen()
 | 
					        def _execute_child(self, *args, **kwargs):
 | 
				
			||||||
 | 
					 | 
				
			||||||
        def _test_fds_execute_child_wrapper(*args, **kwargs):
 | 
					 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                subprocess.Popen._execute_child(p, *args, **kwargs)
 | 
					                subprocess.Popen._execute_child(self, *args, **kwargs)
 | 
				
			||||||
            finally:
 | 
					            finally:
 | 
				
			||||||
                # Open a bunch of file descriptors and verify that
 | 
					                # Open a bunch of file descriptors and verify that
 | 
				
			||||||
                # none of them are the same as the ones the Popen
 | 
					                # none of them are the same as the ones the Popen
 | 
				
			||||||
| 
						 | 
					@ -1059,17 +1052,23 @@ def _test_fds_execute_child_wrapper(*args, **kwargs):
 | 
				
			||||||
                               for _ in range(8)]
 | 
					                               for _ in range(8)]
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    for fd in devzero_fds:
 | 
					                    for fd in devzero_fds:
 | 
				
			||||||
                        self.assertNotIn(fd, (
 | 
					                        self._testcase.assertNotIn(
 | 
				
			||||||
                                p.stdin.fileno(), p.stdout.fileno(),
 | 
					                                fd, (self.stdin.fileno(), self.stdout.fileno(),
 | 
				
			||||||
                                p.stderr.fileno()),
 | 
					                                     self.stderr.fileno()),
 | 
				
			||||||
                                msg="At least one fd was closed early.")
 | 
					                                msg="At least one fd was closed early.")
 | 
				
			||||||
                finally:
 | 
					                finally:
 | 
				
			||||||
                    map(os.close, devzero_fds)
 | 
					                    map(os.close, devzero_fds)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        p._execute_child = _test_fds_execute_child_wrapper
 | 
					    @unittest.skipIf(not os.path.exists("/dev/zero"), "/dev/zero required.")
 | 
				
			||||||
 | 
					    def test_preexec_errpipe_does_not_double_close_pipes(self):
 | 
				
			||||||
 | 
					        """Issue16140: Don't double close pipes on preexec error."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def raise_it():
 | 
				
			||||||
 | 
					            raise RuntimeError("force the _execute_child() errpipe_data path.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.assertRaises(RuntimeError):
 | 
					        with self.assertRaises(RuntimeError):
 | 
				
			||||||
            p.RealPopen([sys.executable, "-c", "pass"],
 | 
					            self._TestExecuteChildPopen(
 | 
				
			||||||
 | 
					                        self, [sys.executable, "-c", "pass"],
 | 
				
			||||||
                        stdin=subprocess.PIPE, stdout=subprocess.PIPE,
 | 
					                        stdin=subprocess.PIPE, stdout=subprocess.PIPE,
 | 
				
			||||||
                        stderr=subprocess.PIPE, preexec_fn=raise_it)
 | 
					                        stderr=subprocess.PIPE, preexec_fn=raise_it)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue