|
1 | 1 | """
|
2 | 2 | A replacement wrapper around the subprocess module, with a number of
|
3 | 3 | work-arounds:
|
4 |
| -- Provides the check_output function (which subprocess only provides from Python |
5 |
| - 2.7 onwards). |
6 | 4 | - Provides a stub implementation of subprocess members on Google App Engine
|
7 | 5 | (which are missing in subprocess).
|
| 6 | +- Use subprocess32, backport from python 3.2 on Linux/Mac work-around for |
| 7 | + https://github.com/matplotlib/matplotlib/issues/5314 |
8 | 8 |
|
9 | 9 | Instead of importing subprocess, other modules should use this as follows:
|
10 | 10 |
|
|
15 | 15 |
|
16 | 16 | from __future__ import absolute_import # Required to import subprocess
|
17 | 17 | from __future__ import print_function
|
18 |
| - |
19 |
| -import subprocess |
| 18 | +import os |
| 19 | +import sys |
| 20 | +if os.name == 'posix' and sys.version_info[:2] < (3, 2): |
| 21 | + # work around for https://github.com/matplotlib/matplotlib/issues/5314 |
| 22 | + try: |
| 23 | + import subprocess32 as subprocess |
| 24 | + except ImportError: |
| 25 | + import subprocess |
| 26 | +else: |
| 27 | + import subprocess |
20 | 28 |
|
21 | 29 | __all__ = ['Popen', 'PIPE', 'STDOUT', 'check_output', 'CalledProcessError']
|
22 | 30 |
|
|
27 | 35 | PIPE = subprocess.PIPE
|
28 | 36 | STDOUT = subprocess.STDOUT
|
29 | 37 | CalledProcessError = subprocess.CalledProcessError
|
| 38 | + check_output = subprocess.check_output |
30 | 39 | else:
|
31 | 40 | # In restricted environments (such as Google App Engine), these are
|
32 | 41 | # non-existent. Replace them with dummy versions that always raise OSError.
|
33 | 42 | def Popen(*args, **kwargs):
|
34 | 43 | raise OSError("subprocess.Popen is not supported")
|
| 44 | + |
| 45 | + def check_output(*args, **kwargs): |
| 46 | + raise OSError("subprocess.check_output is not supported") |
35 | 47 | PIPE = -1
|
36 | 48 | STDOUT = -2
|
37 | 49 | # There is no need to catch CalledProcessError. These stubs cannot raise
|
38 | 50 | # it. None in an except clause will simply not match any exceptions.
|
39 | 51 | CalledProcessError = None
|
40 |
| - |
41 |
| - |
42 |
| -def _check_output(*popenargs, **kwargs): |
43 |
| - r"""Run command with arguments and return its output as a byte |
44 |
| - string. |
45 |
| -
|
46 |
| - If the exit code was non-zero it raises a CalledProcessError. The |
47 |
| - CalledProcessError object will have the return code in the |
48 |
| - returncode |
49 |
| - attribute and output in the output attribute. |
50 |
| -
|
51 |
| - The arguments are the same as for the Popen constructor. Example:: |
52 |
| -
|
53 |
| - >>> check_output(["ls", "-l", "/dev/null"]) |
54 |
| - 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' |
55 |
| -
|
56 |
| - The stdout argument is not allowed as it is used internally. |
57 |
| - To capture standard error in the result, use stderr=STDOUT.:: |
58 |
| -
|
59 |
| - >>> check_output(["/bin/sh", "-c", |
60 |
| - ... "ls -l non_existent_file ; exit 0"], |
61 |
| - ... stderr=STDOUT) |
62 |
| - 'ls: non_existent_file: No such file or directory\n' |
63 |
| - """ |
64 |
| - if 'stdout' in kwargs: |
65 |
| - raise ValueError('stdout argument not allowed, it will be overridden.') |
66 |
| - process = Popen(stdout=PIPE, *popenargs, **kwargs) |
67 |
| - output, unused_err = process.communicate() |
68 |
| - retcode = process.poll() |
69 |
| - if retcode: |
70 |
| - cmd = kwargs.get("args") |
71 |
| - if cmd is None: |
72 |
| - cmd = popenargs[0] |
73 |
| - raise subprocess.CalledProcessError(retcode, cmd, output=output) |
74 |
| - return output |
75 |
| - |
76 |
| - |
77 |
| -# python2.7's subprocess provides a check_output method |
78 |
| -if hasattr(subprocess, 'check_output'): |
79 |
| - check_output = subprocess.check_output |
80 |
| -else: |
81 |
| - check_output = _check_output |
0 commit comments