From 820a326f15c150dde55f047eb924d6e6685bc3c3 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 27 Mar 2013 12:41:08 -0400 Subject: [PATCH] Fixes #1862: The PS backend would inadvertently close file handles passed to it on Python 3. The TextIOWrapper that handles the encoding from unicode to ascii needs to be detached before its destructor is called, otherwise it will call close on the underlying file object. Also cleans up how with statements are handled to avoid the sometimes problematic null contextmanager. --- lib/matplotlib/backends/backend_ps.py | 40 +++++++++++++-------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index dab86b29f2d2..5a829e5f877e 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -5,7 +5,6 @@ # PY3KTODO: Get rid of "print >>fh" syntax from __future__ import division, print_function -import contextlib import glob, math, os, shutil, sys, time def _fn_name(): return sys._getframe(1).f_code.co_name import io @@ -974,11 +973,6 @@ def print_ps(self, outfile, *args, **kwargs): def print_eps(self, outfile, *args, **kwargs): return self._print_ps(outfile, 'eps', *args, **kwargs) - - - - - def _print_ps(self, outfile, format, *args, **kwargs): papertype = kwargs.pop("papertype", rcParams['ps.papersize']) papertype = papertype.lower() @@ -1106,21 +1100,7 @@ def write(self, *kl, **kwargs): self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) - if rcParams['ps.usedistiller']: - # We are going to use an external program to process the output. - # Write to a temporary file. - fd, tmpfile = mkstemp() - context_manager = io.open(fd, 'wb') - else: - # Write directly to outfile. - if passed_in_file_object: - @contextlib.contextmanager - def null_context(value): - yield value - context_manager = null_context(outfile) - else: - context_manager = open(outfile, 'wb') - with context_manager as raw_fh: + def print_figure_impl(): if sys.version_info[0] >= 3: fh = io.TextIOWrapper(raw_fh, encoding="ascii") else: @@ -1195,6 +1175,24 @@ def null_context(value): if not isEPSF: print("%%EOF", file=fh) fh.flush() + if sys.version_info[0] >= 3: + fh.detach() + + if rcParams['ps.usedistiller']: + # We are going to use an external program to process the output. + # Write to a temporary file. + fd, tmpfile = mkstemp() + with io.open(fd, 'wb') as raw_fh: + print_figure_impl() + else: + # Write directly to outfile. + if passed_in_file_object: + raw_fh = outfile + print_figure_impl() + else: + with open(outfile, 'wb') as raw_fh: + print_figure_impl() + if rcParams['ps.usedistiller']: if rcParams['ps.usedistiller'] == 'ghostscript': gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)