10000 Merge pull request #1825 from mgiuca-google/subprocess-google-app-engine · ivanov/matplotlib@8ec9555 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8ec9555

Browse files
committed
Merge pull request matplotlib#1825 from mgiuca-google/subprocess-google-app-engine
Work around missing subprocess members on Google App Engine
2 parents 4703f2f + 03cddc8 commit 8ec9555

File tree

15 files changed

+127
-64
lines changed

15 files changed

+127
-64
lines changed

doc/api/api_changes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ Changes in 1.3.x
3232
by ``self.vline`` for vertical cursors lines and ``self.hline`` is added
3333
for the horizontal cursors lines.
3434

35+
* On POSIX platforms, the :func:`~matplotlib.cbook.report_memory` function
36+
raises :class:`NotImplementedError` instead of :class:`OSError` if the
37+
:command:`ps` command cannot be run.
38+
39+
* The :func:`~matplotlib.cbook.check_output` function has been moved to
40+
`~matplotlib.compat.subprocess`.
41+
3542
Changes in 1.2.x
3643
================
3744

lib/matplotlib/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,15 @@
124124
'.'.join(str(x) for x in _required),
125125
sys.version_info[0]))
126126

127-
import os, re, shutil, subprocess, warnings
127+
import os, re, shutil, warnings
128128
import distutils.sysconfig
129129
import distutils.version
130130

131131
# cbook must import matplotlib only within function
132132
# definitions, so it is safe to import from it here.
133133
from matplotlib.cbook import MatplotlibDeprecationWarning
134134
from matplotlib.cbook import is_string_like
135+
from matplotlib.compat import subprocess
135136

136137
try:
137138
reload

lib/matplotlib/animation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import sys
2121
import itertools
2222
import contextlib
23-
import subprocess
2423
from matplotlib.cbook import iterable, is_string_like
24+
from matplotlib.compat import subprocess
2525
from matplotlib import verbose
2626
from matplotlib import rcParams
2727

lib/matplotlib/backends/backend_pgf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import shutil
88
import tempfile
99
import codecs
10-
import subprocess
1110
import atexit
1211
import weakref
1312

@@ -21,7 +20,8 @@
2120
from matplotlib import font_manager
2221
from matplotlib.ft2font import FT2Font
2322
from matplotlib.cbook import is_string_like, is_writable_file_like
24-
from matplotlib.cbook import check_output
23+
from matplotlib.compat import subprocess
24+
from matplotlib.compat.subprocess import check_output
2525

2626

2727
##### F438 ##########################################################################

lib/matplotlib/backends/backend_ps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def gs_version(self):
8888
except KeyError:
8989
pass
9090

91-
from subprocess import Popen, PIPE
91+
from matplotlib.compat.subprocess import Popen, PIPE
9292
pipe = Popen(self.gs_exe + " --version",
9393
shell=True, stdout=PIPE).stdout
9494
if sys.version_info[0] >= 3:

lib/matplotlib/cbook.py

Lines changed: 22 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import locale
1818
import os
1919
import re
20-
import subprocess
2120
import sys
2221
import threading
2322
import time
@@ -1212,19 +1211,34 @@ def restrict_dict(d, keys):
12121211

12131212
def report_memory(i=0): # argument may go away
12141213
'return the memory consumed by process'
1215-
from subprocess import Popen, PIPE
1214+
from matplotlib.compat.subprocess import Popen, PIPE
12161215
pid = os.getpid()
12171216
if sys.platform == 'sunos5':
1218-
a2 = Popen('ps -p %d -o osz' % pid, shell=True,
1219-
stdout=PIPE).stdout.readlines()
1217+
try:
1218+
a2 = Popen('ps -p %d -o osz' % pid, shell=True,
1219+
stdout=PIPE).stdout.readlines()
1220+
except OSError:
1221+
raise NotImplementedError(
1222+
"report_memory works on Sun OS only if "
1223+
"the 'ps' program is found")
12201224
mem = int(a2[-1].strip())
12211225
elif sys.platform.startswith('linux'):
1222-
a2 = Popen('ps -p %d -o rss,sz' % pid, shell=True,
1223-
stdout=PIPE).stdout.readlines()
1226+
try:
1227+
a2 = Popen('ps -p %d -o rss,sz' % pid, shell=True,
1228+
stdout=PIPE).stdout.readlines()
1229+
except OSError:
1230+
raise NotImplementedError(
1231+
"report_memory works on Linux only if "
1232+
"the 'ps' program is found")
12241233
mem = int(a2[1].split()[1])
12251234
elif sys.platform.startswith('darwin'):
1226-
a2 = Popen('ps -p %d -o rss,vsz' % pid, shell=True,
1227-
stdout=PIPE).stdout.readlines()
1235+
try:
1236+
a2 = Popen('ps -p %d -o rss,vsz' % pid, shell=True,
1237+
stdout=PIPE).stdout.readlines()
1238+
except OSError:
1239+
raise NotImplementedError(
1240+
"report_memory works on Mac OS only if "
1241+
"the 'ps' program is found")
12281242
mem = int(a2[1].split()[0])
12291243
elif sys.platform.startswith('win'):
12301244
try:
@@ -1795,45 +1809,3 @@ def get_instancemethod(self):
17951809
else:
17961810
def _putmask(a, mask, values):
17971811
return np.copyto(a, values, where=mask)
1798-
1799-
1800-
def _check_output(*popenargs, **kwargs):
1801-
r"""Run command with arguments and return its output as a byte
1802-
string.
1803-
1804-
If the exit code was non-zero it raises a CalledProcessError. The
1805-
CalledProcessError object will have the return code in the
1806-
returncode
1807-
attribute and output in the output attribute.
1808-
1809-
The arguments are the same as for the Popen constructor. Example::
1810-
1811-
>>> check_output(["ls", "-l", "/dev/null"])
1812-
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
1813-
1814-
The stdout argument is not allowed as it is used internally.
1815-
To capture standard error in the result, use stderr=STDOUT.::
1816-
1817-
>>> check_output(["/bin/sh", "-c",
1818-
... "ls -l non_existent_file ; exit 0"],
1819-
... stderr=STDOUT)
1820-
'ls: non_existent_file: No such file or directory\n'
1821-
"""
1822-
if 'stdout' in kwargs:
1823-
raise ValueError('stdout argument not allowed, it will be overridden.')
1824-
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
1825-
output, unused_err = process.communicate()
1826-
retcode = process.poll()
1827-
if retcode:
1828-
cmd = kwargs.get("args")
1829-
if cmd is None:
1830-
cmd = popenargs[0]
1831-
raise subprocess.CalledProcessError(retcode, cmd, output=output)
1832-
return output
1833-
1834-
1835-
# python2.7's subprocess provides a check_output method
1836-
if hasattr(subprocess, 'check_output'):
1837-
check_output = subprocess.check_output
1838-
else:
1839-
check_output = _check_output

lib/matplotlib/compat/__init__.py

Whitespace-only changes.

lib/matplotlib/compat/subprocess.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
A replacement wrapper around the subprocess module, with a number of
3+
work-arounds:
4+
- Provides the check_output function (which subprocess only provides from Python
5+
2.7 onwards).
6+
- Provides a stub implementation of subprocess members on Google App Engine
7+
(which are missing in subprocess).
8+
9+
Instead of importing subprocess, other modules should use this as follows:
10+
11+
from matplotlib.compat import subprocess
12+
13+
This module is safe to import from anywhere within matplotlib.
14+
"""
15+
16+
from __future__ import absolute_import # Required to import subprocess
17+
from __future__ import print_function
18+
19+
import subprocess
20+
21+
__all__ = ['Popen', 'PIPE', 'STDOUT', 'check_output']
22+
23+
24+
if hasattr(subprocess, 'Popen'):
25+
Popen = subprocess.Popen
26+
# Assume that it also has the other constants.
27+
PIPE = subprocess.PIPE
28+
STDOUT = subprocess.STDOUT
29+
else:
30+
# In restricted environments (such as Google App Engine), these are
31+
# non-existent. Replace them with dummy versions that always raise OSError.
32+
def Popen(*args, **kwargs):
33+
raise OSError("subprocess.Popen is not supported")
34+
PIPE = -1
35+
STDOUT = -2
36+
37+
38+
def _check_output(*popenargs, **kwargs):
39+
r"""Run command with arguments and return its output as a byte
40+
string.
41+
42+
If the exit code was non-zero it raises a CalledProcessError. The
43+
CalledProcessError object will have the return code in the
44+
returncode
45+
attribute and output in the output attribute.
46+
47+
The arguments are the same as for the Popen constructor. Example::
48+
49+
>>> check_output(["ls", "-l", "/dev/null"])
50+
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
51+
52+
The stdout argument is not allowed as i 10000 t is used internally.
53+
To capture standard error in the result, use stderr=STDOUT.::
54+
55+
>>> check_output(["/bin/sh", "-c",
56+
... "ls -l non_existent_file ; exit 0"],
57+
... stderr=STDOUT)
58+
'ls: non_existent_file: No such file or directory\n'
59+
"""
60+
if 'stdout' in kwargs:
61+
raise ValueError('stdout argument not allowed, it will be overridden.')
62+
process = Popen(stdout=PIPE, *popenargs, **kwargs)
63+
output, unused_err = process.communicate()
64+
retcode = process.poll()
65+
if retcode:
66+
cmd = kwargs.get("args")
67+
if cmd is None:
68+
cmd = popenargs[0]
69+
raise subprocess.CalledProcessError(retcode, cmd, output=output)
70+
return output
71+
72+
73+
# python2.7's subprocess provides a check_output method
74+
if hasattr(subprocess, 'check_output'):
75+
check_output = subprocess.check_output
76+
else:
77+
check_output = _check_output

lib/matplotlib/dviread.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
import errno
2424
import matplotlib
2525
import matplotlib.cbook as mpl_cbook
26+
from matplotlib.compat import subprocess
2627
import numpy as np
2728
import struct
28-
import subprocess
2929
import sys
3030

3131
if sys.version_info[0] >= 3:

lib/matplotlib/font_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
see license/LICENSE_TTFQUERY.
4444
"""
4545

46-
import os, sys, subprocess, warnings
46+
import os, sys, warnings
4747
try:
4848
set
4949
except NameError:
@@ -54,6 +54,7 @@
5454
from matplotlib import rcParams, get_configdir
5555
from matplotlib.cbook import is_string_like
5656
import matplotlib.cbook as cbook
57+
from matplotlib.compat import subprocess
5758
from matplotlib.fontconfig_pattern import \
5859
parse_fontconfig_pattern, generate_fontconfig_pattern
5960

0 commit comments

Comments
 (0)
0