Commit 278d7a4f authored by Jason Madden's avatar Jason Madden

Unify gevent.subprocess.call for Py2/3.

Also temporarily disable a bunch of travis/appveyor builds, I'm
expecting a bunch of commits on this branch.
parent c22e4de9
...@@ -9,16 +9,16 @@ env: ...@@ -9,16 +9,16 @@ env:
matrix: matrix:
# These are ordered to get as much diversity in the # These are ordered to get as much diversity in the
# first group of parallel runs (4) as posible # first group of parallel runs (4) as posible
- TASK=test-py27-noembed # - TASK=test-py27-noembed
- TASK=test-pypy - TASK=test-pypy
- TASK=test-py36 - TASK=test-py36
- TASK=lint-py27 # - TASK=lint-py27
- TASK=test-pypy3 # - TASK=test-pypy3
- TASK=test-py35 # - TASK=test-py35
- TASK=test-py278 # - TASK=test-py278
- TASK=test-py27 - TASK=test-py27
- TASK=test-py34 # - TASK=test-py34
- TASK=test-py27-cffi # - TASK=test-py27-cffi
matrix: matrix:
fast_finish: true fast_finish: true
......
...@@ -17,10 +17,10 @@ environment: ...@@ -17,10 +17,10 @@ environment:
# PYTHON_VERSION: "2.7.x" # PYTHON_VERSION: "2.7.x"
# PYTHON_ARCH: "32" # PYTHON_ARCH: "32"
- PYTHON: "C:\\Python34-x64" # - PYTHON: "C:\\Python34-x64"
PYTHON_VERSION: "3.4.x" # currently 3.4.3 # PYTHON_VERSION: "3.4.x" # currently 3.4.3
PYTHON_ARCH: "64" # PYTHON_ARCH: "64"
PYTHON_EXE: python # PYTHON_EXE: python
- PYTHON: "C:\\Python27-x64" - PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x" # currently 2.7.11 PYTHON_VERSION: "2.7.x" # currently 2.7.11
...@@ -32,30 +32,30 @@ environment: ...@@ -32,30 +32,30 @@ environment:
PYTHON_ARCH: "64" PYTHON_ARCH: "64"
PYTHON_EXE: python PYTHON_EXE: python
- PYTHON: "C:\\Python33-x64" # - PYTHON: "C:\\Python33-x64"
PYTHON_VERSION: "3.3.x" # currently 3.3.5 # PYTHON_VERSION: "3.3.x" # currently 3.3.5
PYTHON_ARCH: "64" # PYTHON_ARCH: "64"
PYTHON_EXE: python # PYTHON_EXE: python
- PYTHON: "C:\\Python35" # - PYTHON: "C:\\Python35"
PYTHON_VERSION: "3.5.x" # currently 3.5.0 # PYTHON_VERSION: "3.5.x" # currently 3.5.0
PYTHON_ARCH: "32" # PYTHON_ARCH: "32"
PYTHON_EXE: python # PYTHON_EXE: python
- PYTHON: "C:\\Python27" # - PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.11 # PYTHON_VERSION: "2.7.x" # currently 2.7.11
PYTHON_ARCH: "32" # PYTHON_ARCH: "32"
PYTHON_EXE: python # PYTHON_EXE: python
- PYTHON: "C:\\Python33" # - PYTHON: "C:\\Python33"
PYTHON_VERSION: "3.3.x" # currently 3.3.5 # PYTHON_VERSION: "3.3.x" # currently 3.3.5
PYTHON_ARCH: "32" # PYTHON_ARCH: "32"
PYTHON_EXE: python # PYTHON_EXE: python
- PYTHON: "C:\\Python34" # - PYTHON: "C:\\Python34"
PYTHON_VERSION: "3.4.x" # currently 3.4.3 # PYTHON_VERSION: "3.4.x" # currently 3.4.3
PYTHON_ARCH: "32" # PYTHON_ARCH: "32"
PYTHON_EXE: python # PYTHON_EXE: python
# Also test a Python version not pre-installed # Also test a Python version not pre-installed
......
...@@ -176,6 +176,8 @@ Other Changes ...@@ -176,6 +176,8 @@ Other Changes
exception; all instances where a ``Timeout`` exception would exception; all instances where a ``Timeout`` exception would
previously be thrown under Python 2 will now throw a previously be thrown under Python 2 will now throw a
``TimeoutExpired`` exception. ``TimeoutExpired`` exception.
- :func:`gevent.subprocess.call` accepts the *timeout* keyword
argument on Python 2.
1.1.2 (Jul 21, 2016) 1.1.2 (Jul 21, 2016)
==================== ====================
......
...@@ -92,6 +92,7 @@ __extra__ = [ ...@@ -92,6 +92,7 @@ __extra__ = [
'_winapi', '_winapi',
# Python 2.5 does not have _subprocess, so we don't use it # Python 2.5 does not have _subprocess, so we don't use it
# XXX We don't run on Py 2.5 anymore; can/could/should we use _subprocess? # XXX We don't run on Py 2.5 anymore; can/could/should we use _subprocess?
# It's only used on mswindows
'WAIT_OBJECT_0', 'WAIT_OBJECT_0',
'WaitForSingleObject', 'WaitForSingleObject',
'GetExitCodeProcess', 'GetExitCodeProcess',
...@@ -206,34 +207,30 @@ else: ...@@ -206,34 +207,30 @@ else:
fork = monkey.get_original('os', 'fork') fork = monkey.get_original('os', 'fork')
from gevent.os import fork_and_watch from gevent.os import fork_and_watch
if PY3: def call(*popenargs, **kwargs):
def call(*popenargs, **kwargs): """
"""Run command with arguments. Wait for command to complete or call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) -> returncode
timeout, then return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:: Run command with arguments. Wait for command to complete or
timeout, then return the returncode attribute.
retcode = call(["ls", "-l"]) The arguments are the same as for the Popen constructor. Example::
"""
timeout = kwargs.pop('timeout', None)
with Popen(*popenargs, **kwargs) as p:
try:
return p.wait(timeout=timeout)
except:
p.kill()
p.wait()
raise
else:
def call(*popenargs, **kwargs):
"""Run command with arguments. Wait for command to complete, then
return the returncode attribute.
The arguments are the same as for the Popen constructor. Example::
retcode = call(["ls", "-l"]) retcode = call(["ls", "-l"])
"""
return Popen(*popenargs, **kwargs).wait()
.. versionchanged:: 1.2a1
The ``timeout`` keyword argument is now accepted on all supported
versions of Python (not just Python 3) and if it expires will raise a
:exc:`TimeoutExpired` exception (under Python 2 this is a subclass of :exc:`~.Timeout`).
"""
timeout = kwargs.pop('timeout', None)
with Popen(*popenargs, **kwargs) as p:
try:
return p.wait(timeout=timeout, _raise_exc=True)
except:
p.kill()
p.wait()
raise
def check_call(*popenargs, **kwargs): def check_call(*popenargs, **kwargs):
"""Run command with arguments. Wait for command to complete. If """Run command with arguments. Wait for command to complete. If
...@@ -747,6 +744,13 @@ class Popen(object): ...@@ -747,6 +744,13 @@ class Popen(object):
# blocks forever. # blocks forever.
self.wait() self.wait()
def _gevent_result_wait(self, timeout=None, raise_exc=PY3):
result = self.result.wait(timeout=timeout)
if raise_exc and timeout is not None and not self.result.ready():
raise TimeoutExpired(self.args, timeout)
return result
if mswindows: if mswindows:
# #
# Windows methods # Windows methods
...@@ -968,17 +972,14 @@ class Popen(object): ...@@ -968,17 +972,14 @@ class Popen(object):
def _wait(self): def _wait(self):
self.threadpool.spawn(self._blocking_wait).rawlink(self.result) self.threadpool.spawn(self._blocking_wait).rawlink(self.result)
def wait(self, timeout=None): def wait(self, timeout=None, _raise_exc=PY3):
"""Wait for child process to terminate. Returns returncode """Wait for child process to terminate. Returns returncode
attribute.""" attribute."""
if self.returncode is None: if self.returncode is None:
if not self._waiting: if not self._waiting:
self._waiting = True self._waiting = True
self._wait() self._wait()
result = self.result.wait(timeout=timeout) return self._gevent_result_wait(timeout, _raise_exc)
if PY3 and timeout is not None and not self.result.ready():
raise TimeoutExpired(self.args, timeout)
return result
def send_signal(self, sig): def send_signal(self, sig):
"""Send a signal to the process """Send a signal to the process
...@@ -1347,7 +1348,7 @@ class Popen(object): ...@@ -1347,7 +1348,7 @@ class Popen(object):
sleep(0.00001) sleep(0.00001)
return self.returncode return self.returncode
def wait(self, timeout=None): def wait(self, timeout=None, _raise_exc=PY3):
""" """
Wait for child process to terminate. Returns :attr:`returncode` Wait for child process to terminate. Returns :attr:`returncode`
attribute. attribute.
...@@ -1358,10 +1359,7 @@ class Popen(object): ...@@ -1358,10 +1359,7 @@ class Popen(object):
this time elapses without finishing the process, this time elapses without finishing the process,
:exc:`TimeoutExpired` is raised. :exc:`TimeoutExpired` is raised.
""" """
result = self.result.wait(timeout=timeout) return self._gevent_result_wait(timeout, _raise_exc)
if PY3 and timeout is not None and not self.result.ready():
raise TimeoutExpired(self.args, timeout)
return result
def send_signal(self, sig): def send_signal(self, sig):
"""Send a signal to the process """Send a signal to the process
...@@ -1416,6 +1414,10 @@ class CompletedProcess(object): ...@@ -1416,6 +1414,10 @@ class CompletedProcess(object):
- returncode: The exit code of the process, negative for signals. - returncode: The exit code of the process, negative for signals.
- stdout: The standard output (None if not captured). - stdout: The standard output (None if not captured).
- stderr: The standard error (None if not captured). - stderr: The standard error (None if not captured).
.. versionadded:: 1.2a1
This first appeared in Python 3.5 and is available to all
Python versions in gevent.
""" """
def __init__(self, args, returncode, stdout=None, stderr=None): def __init__(self, args, returncode, stdout=None, stderr=None):
self.args = args self.args = args
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment