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
Run command with arguments. Wait for command to complete or
timeout, then return the returncode attribute. timeout, then return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:: The arguments are the same as for the Popen constructor. Example::
retcode = call(["ls", "-l"]) retcode = call(["ls", "-l"])
.. 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) timeout = kwargs.pop('timeout', None)
with Popen(*popenargs, **kwargs) as p: with Popen(*popenargs, **kwargs) as p:
try: try:
return p.wait(timeout=timeout) return p.wait(timeout=timeout, _raise_exc=True)
except: except:
p.kill() p.kill()
p.wait() p.wait()
raise 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"])
"""
return Popen(*popenargs, **kwargs).wait()
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