[Python-checkins] cpython: Include the timeout value in TimeoutExpired. (original) (raw)
reid.kleckner python-checkins at python.org
Wed Mar 16 22:10:02 CET 2011
- Previous message: [Python-checkins] cpython (merge 3.2 -> default): Merge #9298 fix.
- Next message: [Python-checkins] cpython: Bump up the subprocess timeouts even more. :(
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
http://hg.python.org/cpython/rev/a161081e8f7c changeset: 68618:a161081e8f7c parent: 68611:6b627e121573 user: Reid Kleckner <reid at kleckner.net> date: Wed Mar 16 16:57:54 2011 -0400 summary: Include the timeout value in TimeoutExpired.
This was the original intention, but it wasn't threaded all the way through due to 'endtime'. Also added a trivial assertion to get coverage of str.
files: Lib/subprocess.py Lib/test/test_subprocess.py
diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -371,8 +371,9 @@ """This exception is raised when the timeout expires while waiting for a child process. """
- def init(self, cmd, output=None):
- def init(self, cmd, timeout, output=None): self.cmd = cmd
def str(self):self.timeout = timeout self.output = output
@@ -533,7 +534,7 @@ except TimeoutExpired: process.kill() output, unused_err = process.communicate()
raise TimeoutExpired(process.args, output=output)
retcode = process.poll() if retcode: raise CalledProcessError(retcode, process.args, output=output)raise TimeoutExpired(process.args, timeout, output=output)
@@ -844,7 +845,7 @@ return (stdout, stderr)
try:
stdout, stderr = self._communicate(input, endtime)
stdout, stderr = self._communicate(input, endtime, timeout) finally: self._communication_started = True
@@ -865,12 +866,12 @@ return endtime - time.time()
- def _check_timeout(self, endtime):
- def _check_timeout(self, endtime, orig_timeout): """Convenience for checking if a timeout has expired.""" if endtime is None: return if time.time() > endtime:
raise TimeoutExpired(self.args)
if mswindows:raise TimeoutExpired(self.args, orig_timeout)
@@ -1063,9 +1064,11 @@ return self.returncode
def wait(self, timeout=None):
def wait(self, timeout=None, endtime=None): """Wait for child process to terminate. Returns returncode attribute."""
if endtime is not None:
timeout = self._remaining_time(endtime) if timeout is None: timeout = _subprocess.INFINITE else:
@@ -1073,7 +1076,7 @@ if self.returncode is None: result = _subprocess.WaitForSingleObject(self._handle, timeout) if result == _subprocess.WAIT_TIMEOUT:
raise TimeoutExpired(self.args)
raise TimeoutExpired(self.args, timeout) self.returncode = _subprocess.GetExitCodeProcess(self._handle) return self.returncode
@@ -1083,7 +1086,7 @@ fh.close()
def _communicate(self, input, endtime):
def _communicate(self, input, endtime, orig_timeout): # Start reader threads feeding into a list hanging off of this # object, unless they've already been started. if self.stdout and not hasattr(self, "_stdout_buff"):
@@ -1489,13 +1492,18 @@ def wait(self, timeout=None, endtime=None): """Wait for child process to terminate. Returns returncode attribute."""
# If timeout was passed but not endtime, compute endtime in terms of
# timeout.
if endtime is None and timeout is not None:
endtime = time.time() + timeout if self.returncode is not None: return self.returncode
elif endtime is not None:
# endtime is preferred to timeout. timeout is only used for
# printing.
if endtime is not None or timeout is not None:
if endtime is None:
endtime = time.time() + timeout
elif timeout is None:
timeout = self._remaining_time(endtime)
if endtime is not None: # Enter a busy loop if we have a timeout. This busy loop was # cribbed from Lib/threading.py in Thread.wait() at r71065. delay = 0.0005 # 500 us -> initial delay of 1 ms
@@ -1507,7 +1515,7 @@ break remaining = self._remaining_time(endtime) if remaining <= 0:
raise TimeoutExpired(self.args)
raise TimeoutExpired(self.args, timeout) delay = min(delay * 2, remaining, .05) time.sleep(delay) elif self.returncode is None:
@@ -1516,7 +1524,7 @@ return self.returncode
def _communicate(self, input, endtime):
def _communicate(self, input, endtime, orig_timeout): if self.stdin and not self._communication_started: # Flush stdio buffer. This might block, if the user has # been writing to .stdin in an uncontrolled fashion.
@@ -1525,9 +1533,11 @@ self.stdin.close()
if _has_poll:
stdout, stderr = self._communicate_with_poll(input, endtime)
stdout, stderr = self._communicate_with_poll(input, endtime,
orig_timeout) else:
stdout, stderr = self._communicate_with_select(input, endtime)
stdout, stderr = self._communicate_with_select(input, endtime,
orig_timeout) self.wait(timeout=self._remaining_time(endtime))
@@ -1550,7 +1560,7 @@ return (stdout, stderr)
def _communicate_with_poll(self, input, endtime):
def _communicate_with_poll(self, input, endtime, orig_timeout): stdout = None # Return stderr = None # Return
@@ -1601,7 +1611,7 @@ if e.args[0] == errno.EINTR: continue raise
self._check_timeout(endtime)
self._check_timeout(endtime, orig_timeout) # XXX Rewrite these to use non-blocking I/O on the # file objects; they are no longer using C stdio!
@@ -1625,7 +1635,7 @@ return (stdout, stderr)
def _communicate_with_select(self, input, endtime):
def _communicate_with_select(self, input, endtime, orig_timeout): if not self._communication_started: self._read_set = [] self._write_set = []
@@ -1667,9 +1677,9 @@ # According to the docs, returning three empty lists indicates # that the timeout expired. if not (rlist or wlist or xlist):
raise TimeoutExpired(self.args)
raise TimeoutExpired(self.args, orig_timeout) # We also check what time it is ourselves for good measure.
self._check_timeout(endtime)
self._check_timeout(endtime, orig_timeout) # XXX Rewrite these to use non-blocking I/O on the # file objects; they are no longer using C stdio!
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -651,7 +651,9 @@ def test_wait_timeout(self): p = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(0.1)"])
self.assertRaises(subprocess.TimeoutExpired, p.wait, timeout=0.01)
with self.assertRaises(subprocess.TimeoutExpired) as c:
p.wait(timeout=0.01)
self.assertIn("0.01", str(c.exception)) # For coverage of __str__. self.assertEqual(p.wait(timeout=2), 0)
-- Repository URL: http://hg.python.org/cpython
- Previous message: [Python-checkins] cpython (merge 3.2 -> default): Merge #9298 fix.
- Next message: [Python-checkins] cpython: Bump up the subprocess timeouts even more. :(
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]