Skip to content

Commit 6501dd9

Browse files
committed
Overhaul external process calls
This commits starts with moving from `os.system` to the `subprocess` module and captures stderr and includes it in the exceptions. For more information see gh-7490.
1 parent bf5aeb5 commit 6501dd9

File tree

3 files changed

+71
-32
lines changed

3 files changed

+71
-32
lines changed

doc/make.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import sys
88
import re
99
import argparse
10+
import subprocess
1011
import matplotlib
1112

1213
def copy_if_out_of_date(original, derived):
@@ -32,10 +33,14 @@ def check_build():
3233
pass
3334

3435
def doctest():
35-
os.system('sphinx-build -b doctest -d build/doctrees . build/doctest')
36+
subprocess.call(
37+
'sphinx-build -b doctest -d build/doctrees . build/doctest',
38+
shell=True)
3639

3740
def linkcheck():
38-
os.system('sphinx-build -b linkcheck -d build/doctrees . build/linkcheck')
41+
subprocess.call(
42+
'sphinx-build -b linkcheck -d build/doctrees . build/linkcheck',
43+
shell=True)
3944

4045
def html(buildername='html'):
4146
check_build()
@@ -52,9 +57,12 @@ def html(buildername='html'):
5257
options = ''
5358
if warnings_as_errors:
5459
options = options + ' -W'
55-
if os.system('sphinx-build -j %d %s -b %s -d build/doctrees . build/%s' % (
56-
n_proc, options, buildername, buildername)):
57-
raise SystemExit("Building HTML failed.")
60+
try:
61+
output = subprocess.check_output('sphinx-build -j %d %s -b %s -d build/doctrees . build/%s' % (
62+
n_proc, options, buildername, buildername), shell=True,
63+
stderr=subprocess.STDOUT)
64+
except subprocess.CalledProcessError as exc:
65+
raise SystemExit("Building HTML failed with %s." % exc.output)
5866

5967
# Clean out PDF files from the _images directory
6068
for filename in glob.glob('build/%s/_images/*.pdf' % buildername):
@@ -78,15 +86,20 @@ def latex():
7886
#figs()
7987
if sys.platform != 'win32':
8088
# LaTeX format.
81-
if os.system('sphinx-build -b latex -d build/doctrees . build/latex'):
82-
raise SystemExit("Building LaTeX failed.")
89+
try:
90+
output = subprocess.check_output('sphinx-build -b latex -d build/doctrees . build/latex',
91+
shell=True, stderr=subprocess.STDOUT)
92+
except subprocess.CalledProcessError as exc:
93+
raise SystemExit("Building LaTeX failed with %s." % exc.output)
8394

8495
# Produce pdf.
8596
os.chdir('build/latex')
8697

8798
# Call the makefile produced by sphinx...
88-
if os.system('make'):
89-
raise SystemExit("Rendering LaTeX failed.")
99+
try:
100+
output = subprocess.check_output('make', stderr=subprocess.STDOUT)
101+
except subprocess.CalledProcessError as exc:
102+
raise SystemExit("Rendering LaTeX failed with %s." % exc.output)
90103

91104
os.chdir('../..')
92105
else:
@@ -97,16 +110,20 @@ def texinfo():
97110
#figs()
98111
if sys.platform != 'win32':
99112
# Texinfo format.
100-
if os.system(
101-
'sphinx-build -b texinfo -d build/doctrees . build/texinfo'):
102-
raise SystemExit("Building Texinfo failed.")
113+
try:
114+
output = subprocess.check_output('sphinx-build -b texinfo -d build/doctrees . build/texinfo',
115+
shell=True, stderr=subprocess.STDOUT)
116+
except subprocess.CalledProcessError as exc:
117+
raise SystemExit("Building Texinfo failed with %s." % exc.output)
103118

104119
# Produce info file.
105120
os.chdir('build/texinfo')
106121

107122
# Call the makefile produced by sphinx...
108-
if os.system('make'):
109-
raise SystemExit("Rendering Texinfo failed.")
123+
try:
124+
output = subprocess.check_output('make', stderr=subprocess.STDOUT)
125+
except subprocess.CalledProcessError as exc:
126+
raise SystemExit("Rendering Texinfo failed with %s." % exc.output)
110127

111128
os.chdir('../..')
112129
else:

lib/matplotlib/backends/backend_ps.py

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import six
99
from six.moves import StringIO
1010

11-
import glob, math, os, shutil, sys, time
11+
import glob, math, os, shutil, sys, subprocess, time
1212
def _fn_name(): return sys._getframe(1).f_code.co_name
1313
import io
1414

@@ -1424,23 +1424,26 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble,
14241424
command = '%s cd "%s" && latex -interaction=nonstopmode "%s" > "%s"'\
14251425
%(precmd, tmpdir, latexfile, outfile)
14261426
verbose.report(command, 'debug')
1427-
exit_status = os.system(command)
1428-
14291427
with io.open(outfile, 'rb') as fh:
1430-
if exit_status:
1428+
try:
1429+
output = subprocess.check_output(command, shell=True,
1430+
stderr=subprocess.STDOUT)
1431+
except subprocess.CalledProcessError as exc:
14311432
raise RuntimeError('LaTeX was not able to process your file:\
1432-
\nHere is the full report generated by LaTeX: \n\n%s'% fh.read())
1433+
and failed with %s.\n\
1434+
\nHere is the full report generated by LaTeX: \n\n%s'% (output, fh.read()))
14331435
else:
14341436
verbose.report(fh.read(), 'debug')
14351437
os.remove(outfile)
14361438

14371439
command = '%s cd "%s" && dvips -q -R0 -o "%s" "%s" > "%s"'%(precmd, tmpdir,
14381440
os.path.split(psfile)[-1], os.path.split(dvifile)[-1], outfile)
14391441
verbose.report(command, 'debug')
1440-
exit_status = os.system(command)
1441-
14421442
with io.open(outfile, 'rb') as fh:
1443-
if exit_status:
1443+
try:
1444+
output = subprocess.check_output(command, shell=True,
1445+
stderr=subprocess.STDOUT)
1446+
except subprocess.CalledProcessError as exc:
14441447
raise RuntimeError('dvips was not able to \
14451448
process the following file:\n%s\nHere is the full report generated by dvips: \
14461449
\n\n'% dvifile + fh.read())
@@ -1495,17 +1498,30 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
14951498
paper_option, psfile, tmpfile, outfile)
14961499

14971500
verbose.report(command, 'debug')
1498-
exit_status = os.system(command)
1501+
with io.open(outfile, 'rb') as fh:
1502+
try:
1503+
output = subprocess.check_output(command, shell=True,
1504+
stderr=subprocess.STDOUT)
1505+
except subprocess.CalledProcessError as exc:
1506+
raise RuntimeError('dvips was not able to \
1507+
process the following file:\n%s\nHere is the full report generated by dvips: \
1508+
\n\n'% dvifile + fh.read())
1509+
else:
1510+
verbose.report(fh.read(), 'debug')
14991511

15001512
with io.open(outfile, 'rb') as fh:
1501-
if exit_status:
1513+
try:
1514+
process_output = subprocess.check_output(command, shell=True,
1515+
stderr=subprocess.STDOUT)
1516+
except subprocess.CalledProcessError as exc:
15021517
output = fh.read()
15031518
m = "\n".join(["ghostscript was not able to process your image.",
1519+
"It failed with %s.",
15041520
"Here is the full report generated by ghostscript:",
15051521
"",
15061522
"%s"])
15071523
# use % to prevent problems with bytes
1508-
raise RuntimeError(m % output)
1524+
raise RuntimeError(m % (process_output, output))
15091525
else:
15101526
verbose.report(fh.read(), 'debug')
15111527
os.remove(outfile)
@@ -1548,23 +1564,28 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
15481564
(paper_option, tmpfile, pdffile, outfile)
15491565
if sys.platform == 'win32': command = command.replace('=', '#')
15501566
verbose.report(command, 'debug')
1551-
exit_status = os.system(command)
1567+
15521568
with io.open(outfile, 'rb') as fh:
1553-
if exit_status:
1569+
try:
1570+
output = subprocess.check_output(command, shell=True,
1571+
stderr=subprocess.STDOUT)
1572+
except subprocess.CalledProcessError as exc:
15541573
raise RuntimeError('ps2pdf was not able to process your \
1555-
image.\n\Here is the report generated by ghostscript:\n\n' + fh.read())
1574+
image and failed with %s.\n\Here is the report generated by ghostscript:\n\n' % (output) + fh.read())
15561575
else:
15571576
verbose.report(fh.read(), 'debug')
15581577
os.remove(outfile)
15591578
command = 'pdftops -paper match -level2 "%s" "%s" > "%s"'% \
15601579
(pdffile, psfile, outfile)
15611580
verbose.report(command, 'debug')
1562-
exit_status = os.system(command)
15631581

15641582
with io.open(outfile, 'rb') as fh:
1565-
if exit_status:
1583+
try:
1584+
output = subprocess.check_output(command, shell=True,
1585+
stderr=subprocess.STDOUT)
1586+
except subprocess.CalledProcessError as exc:
15661587
raise RuntimeError('pdftops was not able to process your \
1567-
image.\nHere is the full report generated by pdftops: \n\n' + fh.read())
1588+
image and failed with %s.\nHere is the full report generated by pdftops: \n\n' % (output) + fh.read())
15681589
else:
15691590
verbose.report(fh.read(), 'debug')
15701591
os.remove(outfile)

tools/subset.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import sys
2929
import getopt
3030
import os
31+
import subprocess
3132
import struct
3233

3334
def log_namelist(nam, unicode):
@@ -145,7 +146,7 @@ def subset_font_raw(font_in, font_out, unicodes, opts):
145146
if pe:
146147
print('Generate("' + font_out + '")', file=pe)
147148
pe.close()
148-
os.system("fontforge -script " + pe_fn)
149+
subprocess.call("fontforge -script " + pe_fn, shell=True)
149150
else:
150151
font.generate(font_out, flags = flags)
151152
font.close()

0 commit comments

Comments
 (0)