Skip to content

Overhaul external process calls #7572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 14, 2017
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
TexManager: Use subprocess instead of os.system
  • Loading branch information
tomspur committed Apr 9, 2017
commit de4acea79231c147c20bf6130f7b6eaa71cac86c
151 changes: 89 additions & 62 deletions lib/matplotlib/texmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from matplotlib import rcParams
from matplotlib._png import read_png
from matplotlib.cbook import mkdirs, Locked
from matplotlib.compat.subprocess import Popen, PIPE, STDOUT
from matplotlib.compat.subprocess import subprocess, Popen, PIPE, STDOUT
import matplotlib.dviread as dviread
import re

Expand Down Expand Up @@ -398,30 +398,33 @@ def make_dvi(self, tex, fontsize):
if DEBUG or not os.path.exists(dvifile):
texfile = self.make_tex(tex, fontsize)
outfile = basefile + '.output'
command = self._get_shell_cmd(
'cd "%s"' % self.texcache,
'latex -interaction=nonstopmode %s > "%s"' %
(os.path.split(texfile)[-1], outfile))
command = [str("latex"), "-interaction=nonstopmode",
os.path.basename(texfile)]
mpl.verbose.report(command, 'debug')
with Locked(self.texcache):
exit_status = os.system(command)
try:
with open(outfile) as fh:
report = fh.read()
except IOError:
report = 'No latex error report available.'
try:
os.stat(dvifile)
exists = True
except OSError:
exists = False
if exit_status or not exists:
raise RuntimeError(
('LaTeX was not able to process the following '
'string:\n%s\nHere is the full report generated by '
'LaTeX: \n\n' % repr(tex.encode('unicode_escape')) +
report))
else:
try:
with open(outfile, "w") as fout:
subprocess.check_call(command,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be changed to check_output as well, I think.

cwd=self.texcache,
stdout=fout,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
try:
with open(outfile) as fh:
report = fh.read()
except IOError:
report = 'No latex error report available.'
raise RuntimeError(
'LaTeX was not able to process the following '
'string:\n%s\nLaTeX failed with: %s\n'
'Here is the full report generated by LaTeX: '
'\n\n' % (repr(tex.encode('unicode_escape')),
report))
try:
with open(outfile) as fh:
report = fh.read()
except IOError:
report = 'No latex error report available.'
mpl.verbose.report(report, 'debug')
for fname in glob.glob(basefile + '*'):
if fname.endswith('dvi'):
Expand Down Expand Up @@ -452,25 +455,34 @@ def make_dvi_preview(self, tex, fontsize):
not os.path.exists(baselinefile)):
texfile = self.make_tex_preview(tex, fontsize)
outfile = basefile + '.output'
command = self._get_shell_cmd(
'cd "%s"' % self.texcache,
'latex -interaction=nonstopmode %s > "%s"' %
(os.path.split(texfile)[-1], outfile))
command = [str("latex"), "-interaction=nonstopmode",
os.path.basename(texfile)]
mpl.verbose.report(command, 'debug')
exit_status = os.system(command)
try:
with open(outfile, "w") as fout:
subprocess.check_call(command,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably can be check_output as well.

cwd=self.texcache,
stdout=fout,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
try:
with open(outfile) as fh:
report = fh.read()
except IOError:
report = 'No latex error report available.'
raise RuntimeError(
('LaTeX was not able to process the following '
'string:\n%s\nLaTeX failed with: %s\n'
'Here is the full report generated by LaTeX: '
'\n\n' % (exc.output,
repr(tex.encode('unicode_escape'))) +
report))
try:
with open(outfile) as fh:
report = fh.read()

except IOError:
report = 'No latex error report available.'
if exit_status:
raise RuntimeError(
('LaTeX was not able to process the following '
'string:\n%s\nHere is the full report generated by '
'LaTeX: \n\n' % repr(tex)) + report)
else:
mpl.verbose.report(report, 'debug')
mpl.verbose.report(report, 'debug')

# find the box extent information in the latex output
# file and store them in ".baseline" file
Expand Down Expand Up @@ -506,25 +518,35 @@ def make_png(self, tex, fontsize, dpi):
if DEBUG or not os.path.exists(pngfile):
dvifile = self.make_dvi(tex, fontsize)
outfile = basefile + '.output'
command = self._get_shell_cmd(
'cd "%s"' % self.texcache,
'dvipng -bg Transparent -D %s -T tight -o "%s" "%s" > "%s"' %
(dpi, os.path.split(pngfile)[-1],
os.path.split(dvifile)[-1], outfile))
command = [str("dvipng"), "-bg", "Transparent", "-D", str(dpi),
"-T", "tight", "-o", os.path.basename(pngfile),
os.path.basename(dvifile)]
mpl.verbose.report(command, 'debug')
exit_status = os.system(command)
try:
with open(outfile, "w") as fout:
subprocess.check_call(command,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check_output as well, I think.

cwd=self.texcache,
stdout=fout,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
try:
with open(outfile) as fh:
report = fh.read()
except IOError:
report = 'No dvipng error report available.'
raise RuntimeError(
('dvipng was not able to process the following '
'string:\n%s\ndvipng failed with: %s\n'
'Here is the full report generated by dvipng: '
'\n\n' % (exc.output,
repr(tex.encode('unicode_escape'))) +
report))
try:
with open(outfile) as fh:
report = fh.read()
except IOError:
report = 'No dvipng error report available.'
if exit_status:
raise RuntimeError(
'dvipng was not able to process the following '
'file:\n%s\nHere is the full report generated by '
'dvipng: \n\n' % dvifile + report)
else:
mpl.verbose.report(report, 'debug')
mpl.verbose.report(report, 'debug')
try:
os.remove(outfile)
except OSError:
Expand All @@ -544,21 +566,26 @@ def make_ps(self, tex, fontsize):
if DEBUG or not os.path.exists(psfile):
dvifile = self.make_dvi(tex, fontsize)
outfile = basefile + '.output'
command = self._get_shell_cmd(
'cd "%s"' % self.texcache,
'dvips -q -E -o "%s" "%s" > "%s"' %
(os.path.split(psfile)[-1],
os.path.split(dvifile)[-1], outfile))
command = [str("dvips"), "-q", "-E", "-o",
os.path.basename(psfile),
os.path.basename(dvifile)]
mpl.verbose.report(command, 'debug')
exit_status = os.system(command)
with open(outfile) as fh:
if exit_status:
try:
with open(outfile, "w") as fout:
subprocess.check_call(command,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another check_output.

cwd=self.texcache,
stdout=fout,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
with open(outfile) as fh:
raise RuntimeError(
'dvipng was not able to process the flowing '
'file:\n%s\nHere is the full report generated by '
'dvipng: \n\n' % dvifile + fh.read())
else:
mpl.verbose.report(fh.read(), 'debug')
('dvipng was not able to process the following '
'file:\n%s\ndvipng failed with: %s\n'
'Here is the full report generated by dvipng: '
'\n\n' % (dvifile, exc.output) +
fh.read()))
with open(outfile) as fh:
mpl.verbose.report(fh.read(), 'debug')
os.remove(outfile)

return psfile
Expand Down