Skip to content

Commit 1c08c16

Browse files
authored
Merge pull request #6576 from jenshnielsen/subprocess_changes2
MNT: Use subprocess32 on python 2.7
2 parents 890071e + c4d126f commit 1c08c16

File tree

4 files changed

+43
-49
lines changed

4 files changed

+43
-49
lines changed

lib/matplotlib/compat/subprocess.py

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"""
22
A replacement wrapper around the subprocess module, with a number of
33
work-arounds:
4-
- Provides the check_output function (which subprocess only provides from Python
5-
2.7 onwards).
64
- Provides a stub implementation of subprocess members on Google App Engine
75
(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
88
99
Instead of importing subprocess, other modules should use this as follows:
1010
@@ -15,8 +15,16 @@
1515

1616
from __future__ import absolute_import # Required to import subprocess
1717
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
2028

2129
__all__ = ['Popen', 'PIPE', 'STDOUT', 'check_output', 'CalledProcessError']
2230

@@ -27,55 +35,17 @@
2735
PIPE = subprocess.PIPE
2836
STDOUT = subprocess.STDOUT
2937
CalledProcessError = subprocess.CalledProcessError
38+
check_output = subprocess.check_output
3039
else:
3140
# In restricted environments (such as Google App Engine), these are
3241
# non-existent. Replace them with dummy versions that always raise OSError.
3342
def Popen(*args, **kwargs):
3443
raise OSError("subprocess.Popen is not supported")
44+
45+
def check_output(*args, **kwargs):
46+
raise OSError("subprocess.check_output is not supported")
3547
PIPE = -1
3648
STDOUT = -2
3749
# There is no need to catch CalledProcessError. These stubs cannot raise
3850
# it. None in an except clause will simply not match any exceptions.
3951
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

lib/matplotlib/tests/test_coding_standards.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ def test_pep8_conformance_installed_files():
217217
'tests/test_subplots.py',
218218
'tests/test_tightlayout.py',
219219
'tests/test_triangulation.py',
220-
'compat/subprocess.py',
221220
'backends/__init__.py',
222221
'backends/backend_agg.py',
223222
'backends/backend_cairo.py',

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
setupext.Six(),
7171
setupext.Dateutil(),
7272
setupext.FuncTools32(),
73+
setupext.Subprocess32(),
7374
setupext.Pytz(),
7475
setupext.Cycler(),
7576
setupext.Tornado(),

setupext.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,8 +1386,8 @@ def check(self):
13861386
import functools32
13871387
except ImportError:
13881388
return (
1389-
"functools32 was not found. It is required for for"
1390-
"python versions prior to 3.2")
1389+
"functools32 was not found. It is required for"
1390+
"Python versions prior to 3.2")
13911391

13921392
return "using functools32"
13931393
else:
@@ -1400,6 +1400,30 @@ def get_install_requires(self):
14001400
return []
14011401

14021402

1403+
class Subprocess32(SetupPackage):
1404+
name = "subprocess32"
1405+
1406+
def check(self):
1407+
if sys.version_info[:2] < (3, 2):
1408+
try:
1409+
import subprocess32
1410+
except ImportError:
1411+
return (
1412+
"subprocess32 was not found. It used "
1413+
" for Python versions prior to 3.2 to improves"
1414+
" functionality on Linux and OSX")
1415+
1416+
return "using subprocess32"
1417+
else:
1418+
return "Not required"
1419+
1420+
def get_install_requires(self):
1421+
if sys.version_info[:2] < (3, 2) and os.name == 'posix':
1422+
return ['subprocess32']
1423+
else:
1424+
return []
1425+
1426+
14031427
class Tornado(OptionalPackage):
14041428
name = "tornado"
14051429

0 commit comments

Comments
 (0)