Commit 4a267f1d authored by Jonathan Michalon's avatar Jonathan Michalon

Merge branch 'subprocess-compat-split' into 'master'

Split subprocess compatibility layers

Split subprocess_compat into several modules to make it easier to maintenance and extend.

Now, instead of having the threading fix in a class derived from the one enabling timeout support, have two classes both derived from subprocess.Popen, and merge them together at the package's root level:

```
               subprocess.Popen
              /                \
._timeout_popen.Popen    ._threaded_popen.Popen
                   \      /
                    .Popen
```

This completely splits up the timeout support and threading fixes, removing any dependency from one on the other, and allows to easily add or remove another compatibility class by simply adding or removing a parent class from the root Popen empty class.
parents e3bd13bb 200fb571
from . import _timeout_popen
from . import _threaded_popen
from ._timeout_popen import TimeoutExpired
from subprocess import PIPE
class Popen(_timeout_popen.Popen, _threaded_popen.Popen):
pass
from sys import hexversion as sys_hexversion
import subprocess
# Fix for bug http://bugs.python.org/issue18851
# FIXME: double check versions
# found in 3.2.0r1, fixed in 3.3.3
# found in 3.4.0, fixed in 3.4.0a1
if not ((sys_hexversion >= 0x030200C1 and sys_hexversion < 0x030303F0) or
(sys_hexversion >= 0x03040000 and sys_hexversion < 0x030400A1)):
class Popen(subprocess.Popen):
pass
else:
# as subprocess.Popen is not atomic when failing to spawn command,
# lock globally (see above)
from threading import Lock
_Popen_lock = Lock()
class Popen(subprocess.Popen):
def __init__(self, *args, **kwargs):
with _Popen_lock:
super().__init__(*args, **kwargs)
from sys import hexversion as sys_hexversion
import subprocess
# Import or implement Popen() with timeout support
if sys_hexversion >= 0x03030000:
# on Python 3.3 Popen() supports timeout, we have nothing to do
from subprocess import TimeoutExpired, PIPE
from subprocess import Popen as _Popen_with_timeout
from subprocess import TimeoutExpired
class Popen(subprocess.Popen):
pass
else:
# on Python < 3.3, implement timeout with a thread
from threading import Thread
import subprocess
from subprocess import PIPE
class TimeoutExpired(subprocess.CalledProcessError):
def __init__(self, args, timeout=None, output=None):
......@@ -20,7 +21,7 @@ else:
return 'Command %s timed out after %g seconds' % (self.args,
self.timeout)
class _Popen_with_timeout(subprocess.Popen):
class Popen(subprocess.Popen):
def __init__(self, args, *pargs, **kwargs):
self.args = args
self._out = None
......@@ -58,24 +59,3 @@ else:
if self._exc:
raise self._exc
return self._out, self._err
# Fix for bug http://bugs.python.org/issue18851
# FIXME: double check versions
# found in 3.2.0r1, fixed in 3.3.3
# found in 3.4.0, fixed in 3.4.0a1
if not ((sys_hexversion >= 0x030200C1 and sys_hexversion < 0x030303F0) or
(sys_hexversion >= 0x03040000 and sys_hexversion < 0x030400A1)):
class Popen(_Popen_with_timeout):
pass
else:
# as subprocess.Popen is not atomic when failing to spawn command,
# lock globally (see above)
from threading import Lock
_Popen_lock = Lock()
class Popen(_Popen_with_timeout):
def __init__(self, *args, **kwargs):
with _Popen_lock:
super().__init__(*args, **kwargs)
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