From 7e8882aa2870bbf3e465e4909c9f6a0d85580b53 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Tue, 6 Dec 2016 00:02:29 +0100 Subject: [PATCH 01/16] 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. --- doc/make.py | 8 +- lib/matplotlib/backends/backend_ps.py | 138 +++++++++++++++----------- tools/subset.py | 3 +- 3 files changed, 87 insertions(+), 62 deletions(-) diff --git a/doc/make.py b/doc/make.py index dd1a4878c3b3..46a0dcedfd0d 100755 --- a/doc/make.py +++ b/doc/make.py @@ -175,8 +175,8 @@ def latex(): os.chdir('build/latex') # Call the makefile produced by sphinx... - if os.system('make'): - raise SystemExit("Rendering LaTeX failed.") + if subprocess.call("make"): + raise SystemExit("Rendering LaTeX failed with.") os.chdir('../..') else: @@ -198,8 +198,8 @@ def texinfo(): os.chdir('build/texinfo') # Call the makefile produced by sphinx... - if os.system('make'): - raise SystemExit("Rendering Texinfo failed.") + if subprocess.call("make"): + raise SystemExit("Rendering Texinfo failed with.") os.chdir('../..') else: diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 167eff74167d..3cc2838a27ff 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -23,6 +23,7 @@ def _fn_name(): return sys._getframe(1).f_code.co_name from matplotlib.cbook import is_string_like, get_realpath_and_stat, \ is_writable_file_like, maxdict, file_requires_unicode +from matplotlib.compat.subprocess import subprocess from matplotlib.figure import Figure from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font @@ -83,8 +84,7 @@ def gs_version(self): pass from matplotlib.compat.subprocess import Popen, PIPE - s = Popen(self.gs_exe + " --version", - shell=True, stdout=PIPE) + s = Popen([self.gs_exe, "--version"], stdout=PIPE) pipe, stderr = s.communicate() if six.PY3: ver = pipe.decode('ascii') @@ -1469,27 +1469,32 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, command = '%s cd "%s" && latex -interaction=nonstopmode "%s" > "%s"'\ %(precmd, tmpdir, latexfile, outfile) verbose.report(command, 'debug') - exit_status = os.system(command) - - with io.open(outfile, 'rb') as fh: - if exit_status: - raise RuntimeError('LaTeX was not able to process your file:\ - \nHere is the full report generated by LaTeX: \n\n%s'% fh.read()) - else: + try: + output = subprocess.check_output(command, shell=True, + stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + with io.open(outfile, 'rb') as fh: + raise RuntimeError('LaTeX was not able to process your file: ' + 'Here is the full report generated by LaTeX' + '\n\n%s'% (fh.read())) + else: + with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') os.remove(outfile) command = '%s cd "%s" && dvips -q -R0 -o "%s" "%s" > "%s"'%(precmd, tmpdir, os.path.split(psfile)[-1], os.path.split(dvifile)[-1], outfile) verbose.report(command, 'debug') - exit_status = os.system(command) - - with io.open(outfile, 'rb') as fh: - if exit_status: - raise RuntimeError('dvips was not able to \ - process the following file:\n%s\nHere is the full report generated by dvips: \ - \n\n'% dvifile + fh.read()) - else: + try: + output = subprocess.check_output(command, shell=True, + stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + with io.open(outfile, 'rb') as fh: + raise RuntimeError('dvips was not able to process the following ' + 'file:\n%s\nHere is the full report generated ' + 'by dvips: \n\n'% dvifile + fh.read()) + else: + with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') os.remove(outfile) os.remove(epsfile) @@ -1528,30 +1533,27 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): outfile = tmpfile + '.output' dpi = rcParams['ps.distiller.res'] - gs_exe = ps_backend_helper.gs_exe if ps_backend_helper.supports_ps2write: # gs version >= 9 device_name = "ps2write" else: device_name = "pswrite" - command = '%s -dBATCH -dNOPAUSE -r%d -sDEVICE=%s %s -sOutputFile="%s" \ - "%s" > "%s"'% (gs_exe, dpi, device_name, - paper_option, psfile, tmpfile, outfile) - + command = [gs_exe, "-dBATCH", "-dNOPAUSE", "-r%d" % dpi, + "-sDEVICE=%s" % device_name, paper_option, + "-sOutputFile=%s" % psfile, tmpfile] verbose.report(command, 'debug') - exit_status = os.system(command) - - with io.open(outfile, 'rb') as fh: - if exit_status: - output = fh.read() - m = "\n".join(["ghostscript was not able to process your image.", - "Here is the full report generated by ghostscript:", - "", - "%s"]) - # use % to prevent problems with bytes - raise RuntimeError(m % output) - else: + try: + with open(outfile, "w") as fout: + subprocess.check_call(command, + stdout=fout, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + with io.open(outfile, 'rb') as fh: + raise RuntimeError('ghostscript was not able to process your ' + 'image.\nHere is the full report generated by ' + 'ghostscript: %s\n\n' % fh.read()) + else: + with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') os.remove(outfile) os.remove(tmpfile) @@ -1584,33 +1586,55 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): psfile = tmpfile + '.ps' outfile = tmpfile + '.output' - if eps: paper_option = "-dEPSCrop" - else: paper_option = "-sPAPERSIZE=%s" % ptype - - command = 'ps2pdf -dAutoFilterColorImages=false \ --dAutoFilterGrayImages=false -sGrayImageFilter=FlateEncode \ --sColorImageFilter=FlateEncode %s "%s" "%s" > "%s"'% \ -(paper_option, tmpfile, pdffile, outfile) - if sys.platform == 'win32': command = command.replace('=', '#') - verbose.report(command, 'debug') - exit_status = os.system(command) - with io.open(outfile, 'rb') as fh: - if exit_status: - raise RuntimeError('ps2pdf was not able to process your \ -image.\nHere is the report generated by ghostscript:\n\n' + fh.read()) + if eps: + paper_option = "-dEPSCrop" + else: + if sys.platform == "win32": + paper_option = "-sPAPERSIZE#%s" % ptype else: + paper_option = "-sPAPERSIZE=%s" % ptype + + if sys.platform == "win32": + command = ["ps2pdf", "-dAutoFilterColorImages#false", + "-dAutoFilterGrayImages#false", + "-sGrayImageFilter#FlateEncode", + "-sColorImageFilter#FlateEncode", paper_option, tmpfile, + pdffile] + else: + command = ["ps2pdf", "-dAutoFilterColorImages=false", + "-dAutoFilterGrayImages=false", + "-sGrayImageFilter=FlateEncode", + "-sColorImageFilter=FlateEncode", paper_option, tmpfile, + pdffile] + verbose.report(command, 'debug') + + try: + with open(outfile, "w") as fout: + subprocess.check_call(command, + stdout=fout, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + with io.open(outfile, 'rb') as fh: + raise RuntimeError('ps2pdf was not able to process your image.\n' + 'Here is the report generated by ps2pdf: ' + '%s\n\n' % fh.read()) + else: + with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') os.remove(outfile) - command = 'pdftops -paper match -level2 "%s" "%s" > "%s"'% \ - (pdffile, psfile, outfile) - verbose.report(command, 'debug') - exit_status = os.system(command) - with io.open(outfile, 'rb') as fh: - if exit_status: - raise RuntimeError('pdftops was not able to process your \ -image.\nHere is the full report generated by pdftops: \n\n' + fh.read()) - else: + command = ["pdftops", "-paper", "match", "-level2", pdffile, psfile] + verbose.report(command, 'debug') + try: + with open(outfile, "w") as fout: + subprocess.check_call(command, + stdout=fout, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + with io.open(outfile, 'rb') as fh: + raise RuntimeError('pdftops was not able to process your image.\n' + 'Here is the full report generated by pdftops: ' + '%s\n\n' % fh.read()) + else: + with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') os.remove(outfile) os.remove(tmpfile) diff --git a/tools/subset.py b/tools/subset.py index 97441c2cfa47..7a17cc22bd14 100644 --- a/tools/subset.py +++ b/tools/subset.py @@ -28,6 +28,7 @@ import sys import getopt import os +import subprocess import struct def log_namelist(nam, unicode): @@ -145,7 +146,7 @@ def subset_font_raw(font_in, font_out, unicodes, opts): if pe: print('Generate("' + font_out + '")', file=pe) pe.close() - os.system("fontforge -script " + pe_fn) + subprocess.call(["fontforge", "-script", pe_fn]) else: font.generate(font_out, flags = flags) font.close() From de4acea79231c147c20bf6130f7b6eaa71cac86c Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 11 Dec 2016 13:14:27 +0100 Subject: [PATCH 02/16] TexManager: Use `subprocess` instead of `os.system` --- lib/matplotlib/texmanager.py | 151 +++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 62 deletions(-) diff --git a/lib/matplotlib/texmanager.py b/lib/matplotlib/texmanager.py index 5ad793057468..e45478c7e7e7 100644 --- a/lib/matplotlib/texmanager.py +++ b/lib/matplotlib/texmanager.py @@ -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 @@ -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, + 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'): @@ -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, + 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 @@ -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, + 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: @@ -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, + 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 From b09e79c05532e26b50e43b40d5ff04509fd3ffa4 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 11 Dec 2016 13:49:10 +0100 Subject: [PATCH 03/16] Use `subprocess` instead `os.system` also in the examples --- examples/pylab_examples/mathtext_examples.py | 4 ++-- examples/pylab_examples/movie_demo.py | 6 +++--- examples/pylab_examples/stix_fonts_demo.py | 4 ++-- examples/tests/backend_driver.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/pylab_examples/mathtext_examples.py b/examples/pylab_examples/mathtext_examples.py index bee528de214d..eac9670bcdc5 100644 --- a/examples/pylab_examples/mathtext_examples.py +++ b/examples/pylab_examples/mathtext_examples.py @@ -3,7 +3,7 @@ """ from __future__ import print_function import matplotlib.pyplot as plt -import os +import subprocess import sys import re import gc @@ -120,6 +120,6 @@ def doall(): fd.write("\\end{document}\n") fd.close() - os.system("pdflatex mathtext_examples.ltx") + subprocess.call(["pdflatex", "mathtext_examples.ltx"]) else: doall() diff --git a/examples/pylab_examples/movie_demo.py b/examples/pylab_examples/movie_demo.py index 0d8e61338257..7e9368f459f0 100644 --- a/examples/pylab_examples/movie_demo.py +++ b/examples/pylab_examples/movie_demo.py @@ -2,7 +2,7 @@ from __future__ import print_function -import os +import subprocess import matplotlib.pyplot as plt import numpy as np @@ -22,8 +22,8 @@ files.append(fname) print('Making movie animation.mpg - this may take a while') -os.system("mencoder 'mf://_tmp*.png' -mf type=png:fps=10 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o animation.mpg") -#os.system("convert _tmp*.png animation.mng") +subprocess.call("mencoder 'mf://_tmp*.png' -mf type=png:fps=10 -ovc lavc " + "-lavcopts vcodec=wmv2 -oac copy -o animation.mpg", shell=True) # cleanup for fname in files: diff --git a/examples/pylab_examples/stix_fonts_demo.py b/examples/pylab_examples/stix_fonts_demo.py index 81bd73575cdc..bbc6828339d0 100644 --- a/examples/pylab_examples/stix_fonts_demo.py +++ b/examples/pylab_examples/stix_fonts_demo.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -import os +import subprocess import sys import re import gc @@ -53,6 +53,6 @@ def doall(): fd.write("\\end{document}\n") fd.close() - os.system("pdflatex stix_fonts_examples.ltx") + subprocess.call(["pdflatex", "stix_fonts_examples.ltx"]) else: doall() diff --git a/examples/tests/backend_driver.py b/examples/tests/backend_driver.py index e084e032f9d8..9433a0b9c43d 100644 --- a/examples/tests/backend_driver.py +++ b/examples/tests/backend_driver.py @@ -349,7 +349,7 @@ def run(arglist): return ret except ImportError: def run(arglist): - os.system(' '.join(arglist)) + os.system(arglist) def drive(backend, directories, python=['python'], switches=[]): @@ -420,7 +420,7 @@ def drive(backend, directories, python=['python'], switches=[]): ret = run(program + [tmpfile_name] + switches) end_time = time.time() print("%s %s" % ((end_time - start_time), ret)) - #os.system('%s %s %s' % (python, tmpfile_name, ' '.join(switches))) + # subprocess.call([python, tmpfile_name] + switches) os.remove(tmpfile_name) if ret: failures.append(fullpath) From 772fbc485ca769b76fa60df181bf0d5f6830b384 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 5 Feb 2017 01:50:14 +0100 Subject: [PATCH 04/16] tests: Remove < 2.7 compat code --- examples/tests/backend_driver.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/examples/tests/backend_driver.py b/examples/tests/backend_driver.py index 9433a0b9c43d..83b768644071 100644 --- a/examples/tests/backend_driver.py +++ b/examples/tests/backend_driver.py @@ -337,19 +337,16 @@ def report_all_missing(directories): ) -try: - import subprocess - - def run(arglist): - try: - ret = subprocess.call(arglist) - except KeyboardInterrupt: - sys.exit() - else: - return ret -except ImportError: - def run(arglist): - os.system(arglist) +from matplotlib.compat import subprocess + + +def run(arglist): + try: + ret = subprocess.call(arglist) + except KeyboardInterrupt: + sys.exit() + else: + return ret def drive(backend, directories, python=['python'], switches=[]): From 742cf62e9b9c29a137f558ea069d658865b5c86d Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 5 Feb 2017 11:01:41 +0100 Subject: [PATCH 05/16] BUG: fix check_output with non-ascii in paths similar to #7715 --- lib/matplotlib/backends/backend_ps.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 3cc2838a27ff..434fefc14749 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -71,7 +71,7 @@ def gs_exe(self): gs_exe = 'gs' self._cached["gs_exe"] = gs_exe - return gs_exe + return str(gs_exe) @property def gs_version(self): @@ -1539,7 +1539,7 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): else: device_name = "pswrite" - command = [gs_exe, "-dBATCH", "-dNOPAUSE", "-r%d" % dpi, + command = [str(gs_exe), "-dBATCH", "-dNOPAUSE", "-r%d" % dpi, "-sDEVICE=%s" % device_name, paper_option, "-sOutputFile=%s" % psfile, tmpfile] verbose.report(command, 'debug') @@ -1595,13 +1595,13 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): paper_option = "-sPAPERSIZE=%s" % ptype if sys.platform == "win32": - command = ["ps2pdf", "-dAutoFilterColorImages#false", + command = [str("ps2pdf"), "-dAutoFilterColorImages#false", "-dAutoFilterGrayImages#false", "-sGrayImageFilter#FlateEncode", "-sColorImageFilter#FlateEncode", paper_option, tmpfile, pdffile] else: - command = ["ps2pdf", "-dAutoFilterColorImages=false", + command = [str("ps2pdf"), "-dAutoFilterColorImages=false", "-dAutoFilterGrayImages=false", "-sGrayImageFilter=FlateEncode", "-sColorImageFilter=FlateEncode", paper_option, tmpfile, @@ -1622,7 +1622,7 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): verbose.report(fh.read(), 'debug') os.remove(outfile) - command = ["pdftops", "-paper", "match", "-level2", pdffile, psfile] + command = [str("pdftops"), "-paper", "match", "-level2", pdffile, psfile] verbose.report(command, 'debug') try: with open(outfile, "w") as fout: From 9bf01c67fbfdfd640ca63f6785a7ff9b3eeefc5b Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Fri, 24 Feb 2017 18:15:31 +0100 Subject: [PATCH 06/16] doc/make.py: Use cwd in check_output instead of os.chdir --- doc/make.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/doc/make.py b/doc/make.py index 46a0dcedfd0d..378cbb6973b3 100755 --- a/doc/make.py +++ b/doc/make.py @@ -172,13 +172,9 @@ def latex(): raise SystemExit("Building LaTeX failed.") # Produce pdf. - os.chdir('build/latex') - # Call the makefile produced by sphinx... - if subprocess.call("make"): + if subprocess.call("make", cwd="build/latex"): raise SystemExit("Rendering LaTeX failed with.") - - os.chdir('../..') else: print('latex build has not been tested on windows') @@ -195,13 +191,9 @@ def texinfo(): raise SystemExit("Building Texinfo failed.") # Produce info file. - os.chdir('build/texinfo') - # Call the makefile produced by sphinx... - if subprocess.call("make"): + if subprocess.call("make", cwd="build/texinfo"): raise SystemExit("Rendering Texinfo failed with.") - - os.chdir('../..') else: print('texinfo build has not been tested on windows') From 8844fd4807a08d8034b94dcc7897035cc1f456ec Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Tue, 28 Mar 2017 09:00:02 +0200 Subject: [PATCH 07/16] backend_ps: Try to fix UnicodeError The full traceback leads to here: lib/matplotlib/backends/backend_ps.py:1537: in gs_distill if ps_backend_helper.supports_ps2write: # gs version >= 9 lib/matplotlib/backends/backend_ps.py:106: in supports_ps2write return self.gs_version[0] >= 9 lib/matplotlib/backends/backend_ps.py:87: in gs_version s = Popen([self.gs_exe, "--version"], stdout=PIPE) venv/lib/python2.7/site-packages/subprocess32.py:825: in __init__ restore_signals, start_new_session) venv/lib/python2.7/site-packages/subprocess32.py:1387: in _execute_child for exe in executable_list) venv/lib/python2.7/site-packages/subprocess32.py:1386: in executable_list = tuple(fs_encode(exe) venv/lib/python2.7/site-packages/subprocess32.py:1385: in for dir in path_list) --- lib/matplotlib/backends/backend_ps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 434fefc14749..67a616e006ff 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -84,7 +84,7 @@ def gs_version(self): pass from matplotlib.compat.subprocess import Popen, PIPE - s = Popen([self.gs_exe, "--version"], stdout=PIPE) + s = Popen([str(self.gs_exe), "--version"], stdout=PIPE) pipe, stderr = s.communicate() if six.PY3: ver = pipe.decode('ascii') From 6d189b39a4ac91e12d5ce7d54dac62f8e264fe35 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Tue, 28 Mar 2017 09:20:34 +0200 Subject: [PATCH 08/16] Remove precmd from backend_ps and use subprocess --- lib/matplotlib/backends/backend_ps.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 67a616e006ff..9f845ed4c0f7 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -1458,20 +1458,17 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, "rcParam.", 'helpful') raise - # the split drive part of the command is necessary for windows users with - # multiple - if sys.platform == 'win32': precmd = '%s &&'% os.path.splitdrive(tmpdir)[0] - else: precmd = '' #Replace \\ for / so latex does not think there is a function call latexfile = latexfile.replace("\\", "/") # Replace ~ so Latex does not think it is line break latexfile = latexfile.replace("~", "\\string~") - command = '%s cd "%s" && latex -interaction=nonstopmode "%s" > "%s"'\ - %(precmd, tmpdir, latexfile, outfile) + command = [str("latex"), "-interaction=nonstopmode", + '"%s"' % latexfile] verbose.report(command, 'debug') try: - output = subprocess.check_output(command, shell=True, - stderr=subprocess.STDOUT) + with open(outfile, "w") as fout: + subprocess.check_call(command, cwd=tmpdir, + stdout=fout, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: with io.open(outfile, 'rb') as fh: raise RuntimeError('LaTeX was not able to process your file: ' @@ -1482,12 +1479,13 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, verbose.report(fh.read(), 'debug') os.remove(outfile) - command = '%s cd "%s" && dvips -q -R0 -o "%s" "%s" > "%s"'%(precmd, tmpdir, - os.path.split(psfile)[-1], os.path.split(dvifile)[-1], outfile) + command = [str('dvips'), '-q', '-R0', '-o', os.path.basename(psfile), + os.path.basename(dvifile)] verbose.report(command, 'debug') try: - output = subprocess.check_output(command, shell=True, - stderr=subprocess.STDOUT) + with open(outfile, "w") as fout: + subprocess.check_call(command, cwd=tmpdir, + stdout=fout, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: with io.open(outfile, 'rb') as fh: raise RuntimeError('dvips was not able to process the following ' From 982ade1309cc1a64dd5068260ce860d97c88afc6 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Mon, 3 Apr 2017 22:09:32 +0200 Subject: [PATCH 09/16] backend_ps: Print strings explicitely when printing error report --- lib/matplotlib/backends/backend_ps.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 9f845ed4c0f7..2c7e16520857 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -1471,9 +1471,10 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, stdout=fout, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: with io.open(outfile, 'rb') as fh: - raise RuntimeError('LaTeX was not able to process your file: ' - 'Here is the full report generated by LaTeX' - '\n\n%s'% (fh.read())) + raise RuntimeError('LaTeX was not able to process the following ' + 'file:\n%s\n' + 'Here is the full report generated by LaTeX:' + '%s\n\n' % (latexfile, fh.read())) else: with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') @@ -1485,12 +1486,12 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, try: with open(outfile, "w") as fout: subprocess.check_call(command, cwd=tmpdir, - stdout=fout, stderr=subprocess.STDOUT) + stdout=fout, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: with io.open(outfile, 'rb') as fh: raise RuntimeError('dvips was not able to process the following ' 'file:\n%s\nHere is the full report generated ' - 'by dvips: \n\n'% dvifile + fh.read()) + 'by dvips: %s \n\n' % (dvifile, fh.read())) else: with io.open(outfile, 'rb') as fh: verbose.report(fh.read(), 'debug') From 24ce833768f8a9d327d0143a5d644d5f416769f5 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 9 Apr 2017 11:53:32 +0200 Subject: [PATCH 10/16] subprocess: Use check_output instead of check_call --- lib/matplotlib/backends/backend_ps.py | 98 +++++++++------------- lib/matplotlib/texmanager.py | 113 +++++++------------------- 2 files changed, 68 insertions(+), 143 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 2c7e16520857..79ab026f76c7 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -1412,7 +1412,6 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, epsfile = tmpfile+'.eps' shutil.move(tmpfile, epsfile) latexfile = tmpfile+'.tex' - outfile = tmpfile+'.output' dvifile = tmpfile+'.dvi' psfile = tmpfile+'.ps' @@ -1458,7 +1457,7 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, "rcParam.", 'helpful') raise - #Replace \\ for / so latex does not think there is a function call + # Replace \\ for / so latex does not think there is a function call latexfile = latexfile.replace("\\", "/") # Replace ~ so Latex does not think it is line break latexfile = latexfile.replace("~", "\\string~") @@ -1466,36 +1465,31 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, '"%s"' % latexfile] verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, cwd=tmpdir, - stdout=fout, stderr=subprocess.STDOUT) + report = subprocess.check_output(command, cwd=tmpdir, + stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: - with io.open(outfile, 'rb') as fh: - raise RuntimeError('LaTeX was not able to process the following ' - 'file:\n%s\n' - 'Here is the full report generated by LaTeX:' - '%s\n\n' % (latexfile, fh.read())) - else: - with io.open(outfile, 'rb') as fh: - verbose.report(fh.read(), 'debug') - os.remove(outfile) + raise RuntimeError( + ('LaTeX was not able to process the following ' + 'file:\n%s\n\n' + 'Here is the full report generated by LaTeX:\n%s ' + '\n\n' % (latexfile, + exc.output.decode("utf-8")))) + verbose.report(report, 'debug') command = [str('dvips'), '-q', '-R0', '-o', os.path.basename(psfile), os.path.basename(dvifile)] verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, cwd=tmpdir, - stdout=fout, stderr=subprocess.STDOUT) + report = subprocess.check_output(command, cwd=tmpdir, + stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: - with io.open(outfile, 'rb') as fh: - raise RuntimeError('dvips was not able to process the following ' - 'file:\n%s\nHere is the full report generated ' - 'by dvips: %s \n\n' % (dvifile, fh.read())) - else: - with io.open(outfile, 'rb') as fh: - verbose.report(fh.read(), 'debug') - os.remove(outfile) + raise RuntimeError( + ('dvips was not able to process the following ' + 'file:\n%s\n\n' + 'Here is the full report generated by dvips:\n%s ' + '\n\n' % (dvifile, + exc.output.decode("utf-8")))) + verbose.report(report, 'debug') os.remove(epsfile) shutil.move(psfile, tmpfile) @@ -1529,7 +1523,6 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): else: paper_option = "-sPAPERSIZE=%s" % ptype psfile = tmpfile + '.ps' - outfile = tmpfile + '.output' dpi = rcParams['ps.distiller.res'] gs_exe = ps_backend_helper.gs_exe @@ -1543,18 +1536,13 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): "-sOutputFile=%s" % psfile, tmpfile] verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - stdout=fout, stderr=subprocess.STDOUT) + report = subprocess.check_output(command, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: - with io.open(outfile, 'rb') as fh: - raise RuntimeError('ghostscript was not able to process your ' - 'image.\nHere is the full report generated by ' - 'ghostscript: %s\n\n' % fh.read()) - else: - with io.open(outfile, 'rb') as fh: - verbose.report(fh.read(), 'debug') - os.remove(outfile) + raise RuntimeError( + ('ghostscript was not able to process your image.\n' + 'Here is the full report generated by ghostscript:\n%s ' + '\n\n' % exc.output.decode("utf-8"))) + verbose.report(report, 'debug') os.remove(tmpfile) shutil.move(psfile, tmpfile) @@ -1583,7 +1571,6 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): """ pdffile = tmpfile + '.pdf' psfile = tmpfile + '.ps' - outfile = tmpfile + '.output' if eps: paper_option = "-dEPSCrop" @@ -1608,34 +1595,24 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - stdout=fout, stderr=subprocess.STDOUT) + report = subprocess.check_output(command, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: - with io.open(outfile, 'rb') as fh: - raise RuntimeError('ps2pdf was not able to process your image.\n' - 'Here is the report generated by ps2pdf: ' - '%s\n\n' % fh.read()) - else: - with io.open(outfile, 'rb') as fh: - verbose.report(fh.read(), 'debug') - os.remove(outfile) + raise RuntimeError( + ('ps2pdf was not able to process your image.\n' + 'Here is the full report generated by ps2pdf:\n%s ' + '\n\n' % exc.output.decode("utf-8"))) + verbose.report(report, 'debug') command = [str("pdftops"), "-paper", "match", "-level2", pdffile, psfile] verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - stdout=fout, stderr=subprocess.STDOUT) + report = subprocess.check_output(command, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: - with io.open(outfile, 'rb') as fh: - raise RuntimeError('pdftops was not able to process your image.\n' - 'Here is the full report generated by pdftops: ' - '%s\n\n' % fh.read()) - else: - with io.open(outfile, 'rb') as fh: - verbose.report(fh.read(), 'debug') - os.remove(outfile) + raise RuntimeError( + ('pdftops was not able to process your image.\n' + 'Here is the full report generated by pdftops:\n%s ' + '\n\n' % exc.output.decode("utf-8"))) + verbose.report(report, 'debug') os.remove(tmpfile) shutil.move(psfile, tmpfile) @@ -1670,7 +1647,6 @@ def get_bbox(tmpfile, bbox): an appropriately sized bbox centered around that point. A bit of a hack. """ - outfile = tmpfile + '.output' gs_exe = ps_backend_helper.gs_exe command = '%s -dBATCH -dNOPAUSE -sDEVICE=bbox "%s"' %\ (gs_exe, tmpfile) diff --git a/lib/matplotlib/texmanager.py b/lib/matplotlib/texmanager.py index e45478c7e7e7..d86bc91b7adc 100644 --- a/lib/matplotlib/texmanager.py +++ b/lib/matplotlib/texmanager.py @@ -397,34 +397,21 @@ def make_dvi(self, tex, fontsize): if DEBUG or not os.path.exists(dvifile): texfile = self.make_tex(tex, fontsize) - outfile = basefile + '.output' command = [str("latex"), "-interaction=nonstopmode", os.path.basename(texfile)] mpl.verbose.report(command, 'debug') with Locked(self.texcache): try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - cwd=self.texcache, - stdout=fout, - stderr=subprocess.STDOUT) + report = subprocess.check_output(command, + cwd=self.texcache, + 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: ' + ('LaTeX was not able to process the following ' + 'string:\n%s\n\n' + 'Here is the full report generated by LaTeX:\n%s ' '\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.' + exc.output.decode("utf-8")))) mpl.verbose.report(report, 'debug') for fname in glob.glob(basefile + '*'): if fname.endswith('dvi'): @@ -454,34 +441,20 @@ def make_dvi_preview(self, tex, fontsize): if (DEBUG or not os.path.exists(dvifile) or not os.path.exists(baselinefile)): texfile = self.make_tex_preview(tex, fontsize) - outfile = basefile + '.output' command = [str("latex"), "-interaction=nonstopmode", os.path.basename(texfile)] mpl.verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - cwd=self.texcache, - stdout=fout, - stderr=subprocess.STDOUT) + report = subprocess.check_output(command, + cwd=self.texcache, + 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.' + 'string:\n%s\n\n' + 'Here is the full report generated by LaTeX:\n%s ' + '\n\n' % (repr(tex.encode('unicode_escape')), + exc.output.decode("utf-8")))) mpl.verbose.report(report, 'debug') # find the box extent information in the latex output @@ -517,40 +490,22 @@ def make_png(self, tex, fontsize, dpi): # see get_rgba for a discussion of the background if DEBUG or not os.path.exists(pngfile): dvifile = self.make_dvi(tex, fontsize) - outfile = basefile + '.output' command = [str("dvipng"), "-bg", "Transparent", "-D", str(dpi), "-T", "tight", "-o", os.path.basename(pngfile), os.path.basename(dvifile)] mpl.verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - cwd=self.texcache, - stdout=fout, - stderr=subprocess.STDOUT) + report = subprocess.check_output(command, + cwd=self.texcache, + 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.' + 'string:\n%s\n\n' + 'Here is the full report generated by dvipng:\n%s ' + '\n\n' % (repr(tex.encode('unicode_escape')), + exc.output.decode("utf-8")))) mpl.verbose.report(report, 'debug') - try: - os.remove(outfile) - except OSError: - pass return pngfile @@ -565,28 +520,22 @@ def make_ps(self, tex, fontsize): if DEBUG or not os.path.exists(psfile): dvifile = self.make_dvi(tex, fontsize) - outfile = basefile + '.output' command = [str("dvips"), "-q", "-E", "-o", os.path.basename(psfile), os.path.basename(dvifile)] mpl.verbose.report(command, 'debug') try: - with open(outfile, "w") as fout: - subprocess.check_call(command, - cwd=self.texcache, - stdout=fout, - stderr=subprocess.STDOUT) + report = subprocess.check_output(command, + cwd=self.texcache, + stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: - with open(outfile) as fh: - raise RuntimeError( - ('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) + raise RuntimeError( + ('dvips was not able to process the following ' + 'string:\n%s\n\n' + 'Here is the full report generated by dvips:\n%s ' + '\n\n' % (repr(tex.encode('unicode_escape')), + exc.output.decode("utf-8")))) + mpl.verbose.report(report, 'debug') return psfile From 01491c023b94d7d62f49a272999a06d8699ef7a3 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 9 Apr 2017 11:58:57 +0200 Subject: [PATCH 11/16] backend_ps: remove uneeded imports and fix some pep8 errors --- lib/matplotlib/backends/backend_ps.py | 36 +++++++++++++-------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 79ab026f76c7..eefe966f1f0b 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -8,15 +8,12 @@ import six from six.moves import StringIO -import glob, math, os, shutil, sys, time, datetime +import glob, os, shutil, sys, time, datetime def _fn_name(): return sys._getframe(1).f_code.co_name import io -from hashlib import md5 - from tempfile import mkstemp from matplotlib import verbose, __version__, rcParams, checkdep_ghostscript -from matplotlib._pylab_helpers import Gcf from matplotlib.afm import AFM from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase @@ -31,7 +28,6 @@ def _fn_name(): return sys._getframe(1).f_code.co_name from matplotlib.ttconv import convert_ttf_to_ps from matplotlib.mathtext import MathTextParser from matplotlib._mathtext_data import uni2type1 -from matplotlib.text import Text from matplotlib.path import Path from matplotlib import _path from matplotlib.transforms import Affine2D @@ -474,8 +470,6 @@ def draw_image(self, gc, x, y, im, transform=None): self._pswriter.write(ps) def _convert_path(self, path, transform, clip=False, simplify=None): - ps = [] - last_points = None if clip: clip = (0.0, 0.0, self.width * 72.0, self.height * 72.0) @@ -516,8 +510,6 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None) """ if debugPS: self._pswriter.write('% draw_markers \n') - write = self._pswriter.write - if rgbFace: if rgbFace[0]==rgbFace[1] and rgbFace[0]==rgbFace[2]: ps_color = '%1.3f setgray' % rgbFace[0] @@ -885,7 +877,6 @@ def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None): write("grestore\n") - class GraphicsContextPS(GraphicsContextBase): def get_capstyle(self): return {'butt':0, @@ -901,6 +892,7 @@ def shouldstroke(self): return (self.get_linewidth() > 0.0 and (len(self.get_rgb()) <= 3 or self.get_rgb()[3] != 0.0)) + def new_figure_manager(num, *args, **kwargs): FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) @@ -915,6 +907,7 @@ def new_figure_manager_given_figure(num, figure): manager = FigureManagerPS(canvas, num) return manager + class FigureCanvasPS(FigureCanvasBase): _renderer_class = RendererPS @@ -1415,8 +1408,10 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, dvifile = tmpfile+'.dvi' psfile = tmpfile+'.ps' - if orientation=='landscape': angle = 90 - else: angle = 0 + if orientation == 'landscape': + angle = 90 + else: + angle = 0 if rcParams['text.latex.unicode']: unicode_preamble = """\\usepackage{ucs} @@ -1519,8 +1514,10 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): operators. The output is low-level, converting text to outlines. """ - if eps: paper_option = "-dEPSCrop" - else: paper_option = "-sPAPERSIZE=%s" % ptype + if eps: + paper_option = "-dEPSCrop" + else: + paper_option = "-sPAPERSIZE=%s" % ptype psfile = tmpfile + '.ps' dpi = rcParams['ps.distiller.res'] @@ -1622,6 +1619,7 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): for fname in glob.glob(tmpfile+'.*'): os.remove(fname) + def get_bbox_header(lbrt, rotated=False): """ return a postscript header stringfor the given bbox lbrt=(l, b, r, t). @@ -1629,7 +1627,7 @@ def get_bbox_header(lbrt, rotated=False): """ l, b, r, t = lbrt - if rotated: + if rotated: rotate = "%.2f %.2f translate\n90 rotate" % (l+r, 0) else: rotate = "" @@ -1643,13 +1641,13 @@ def get_bbox_header(lbrt, rotated=False): # find the bounding box, as the required bounding box is alread known. def get_bbox(tmpfile, bbox): """ - Use ghostscript's bbox device to find the center of the bounding box. Return - an appropriately sized bbox centered around that point. A bit of a hack. + Use ghostscript's bbox device to find the center of the bounding box. + Return an appropriately sized bbox centered around that point. A bit of a + hack. """ gs_exe = ps_backend_helper.gs_exe - command = '%s -dBATCH -dNOPAUSE -sDEVICE=bbox "%s"' %\ - (gs_exe, tmpfile) + command = '%s -dBATCH -dNOPAUSE -sDEVICE=bbox "%s"' % (gs_exe, tmpfile) verbose.report(command, 'debug') stdin, stdout, stderr = os.popen3(command) verbose.report(stdout.read(), 'debug-annoying') From dbb0115ef27c2ebc54de0ddfcba34d00dcab552c Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 9 Apr 2017 12:15:59 +0200 Subject: [PATCH 12/16] TexManager: transform bytes-object to string before searching for box information --- lib/matplotlib/texmanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/texmanager.py b/lib/matplotlib/texmanager.py index d86bc91b7adc..1bfecd69c8ee 100644 --- a/lib/matplotlib/texmanager.py +++ b/lib/matplotlib/texmanager.py @@ -459,7 +459,7 @@ def make_dvi_preview(self, tex, fontsize): # find the box extent information in the latex output # file and store them in ".baseline" file - m = TexManager._re_vbox.search(report) + m = TexManager._re_vbox.search(report.decode("utf-8")) with open(basefile + '.baseline', "w") as fh: fh.write(" ".join(m.groups())) From f56dd1367c68d26bd1fa28c0e2c37cedc1887269 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Sun, 9 Apr 2017 17:34:52 +0200 Subject: [PATCH 13/16] TexManager: Remove unneeded _get_shell_cmd --- lib/matplotlib/texmanager.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/matplotlib/texmanager.py b/lib/matplotlib/texmanager.py index 1bfecd69c8ee..0b151bc139aa 100644 --- a/lib/matplotlib/texmanager.py +++ b/lib/matplotlib/texmanager.py @@ -263,18 +263,6 @@ def get_custom_preamble(self): """returns a string containing user additions to the tex preamble""" return '\n'.join(rcParams['text.latex.preamble']) - def _get_shell_cmd(self, *args): - """ - On windows, changing directories can be complicated by the presence of - multiple drives. get_shell_cmd deals with this issue. - """ - if sys.platform == 'win32': - command = ['%s' % os.path.splitdrive(self.texcache)[0]] - else: - command = [] - command.extend(args) - return ' && '.join(command) - def make_tex(self, tex, fontsize): """ Generate a tex file to render the tex string at a specific font size From c3b481b3dc1642733dd295fc7c056c5075afb46f Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Thu, 13 Apr 2017 10:14:55 +0200 Subject: [PATCH 14/16] Fix typo: 'determin' --- lib/matplotlib/texmanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/texmanager.py b/lib/matplotlib/texmanager.py index 0b151bc139aa..8eae5fcc51a6 100644 --- a/lib/matplotlib/texmanager.py +++ b/lib/matplotlib/texmanager.py @@ -315,7 +315,7 @@ def make_tex(self, tex, fontsize): def make_tex_preview(self, tex, fontsize): """ Generate a tex file to render the tex string at a specific - font size. It uses the preview.sty to determin the dimension + font size. It uses the preview.sty to determine the dimension (width, height, descent) of the output. returns the file name From 79d71cc91fbcd186657f4d203385106b9e65cabe Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Thu, 13 Apr 2017 10:15:23 +0200 Subject: [PATCH 15/16] backend_ps: replace os.popen3 -> subprocess.Popen --- lib/matplotlib/backends/backend_ps.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index eefe966f1f0b..b0950927d179 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -66,7 +66,7 @@ def gs_exe(self): if gs_exe is None: gs_exe = 'gs' - self._cached["gs_exe"] = gs_exe + self._cached["gs_exe"] = str(gs_exe) return str(gs_exe) @property @@ -1647,9 +1647,12 @@ def get_bbox(tmpfile, bbox): """ gs_exe = ps_backend_helper.gs_exe - command = '%s -dBATCH -dNOPAUSE -sDEVICE=bbox "%s"' % (gs_exe, tmpfile) + command = [gs_exe, "-dBATCH", "-dNOPAUSE", "-sDEVICE=bbox" "%s" % tmpfile] verbose.report(command, 'debug') - stdin, stdout, stderr = os.popen3(command) + p = subprocess.Popen(command, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + close_fds=True) + (stdout, stderr) = (p.stdout, p.stderr) verbose.report(stdout.read(), 'debug-annoying') bbox_info = stderr.read() verbose.report(bbox_info, 'helpful') @@ -1658,7 +1661,7 @@ def get_bbox(tmpfile, bbox): bbox_info = bbox_found.group() else: raise RuntimeError('Ghostscript was not able to extract a bounding box.\ -Here is the Ghostscript output:\n\n%s'% bbox_info) +Here is the Ghostscript output:\n\n%s' % bbox_info) l, b, r, t = [float(i) for i in bbox_info.split()[-4:]] # this is a hack to deal with the fact that ghostscript does not return the From d579266e5d5d087294c4edfe1224b88b4826d214 Mon Sep 17 00:00:00 2001 From: Thomas Spura Date: Thu, 13 Apr 2017 10:17:16 +0200 Subject: [PATCH 16/16] backend_ps: remove one not needed str casting --- lib/matplotlib/backends/backend_ps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index b0950927d179..72d9d6f0f39f 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -80,7 +80,7 @@ def gs_version(self): pass from matplotlib.compat.subprocess import Popen, PIPE - s = Popen([str(self.gs_exe), "--version"], stdout=PIPE) + s = Popen([self.gs_exe, "--version"], stdout=PIPE) pipe, stderr = s.communicate() if six.PY3: ver = pipe.decode('ascii')