Skip to content
This repository

backend_ps: Do not write to a temporary file unless using an external distiller #1826

Merged
merged 1 commit into from about 1 year ago

3 participants

Matt Giuca Phil Elson Michael Droettboom
Matt Giuca

If ps.usedistiller is omitted, writes directly to the output file, instead of creating a temporary file and subsequently copying it to the output.

This is more efficient, and also works on restricted platforms such as Google App Engine, which are unable to provide a writable temporary file system.

Partial fix for Issue #1823.

Phil Elson
Collaborator

I'm not sure who our resident PS expert is. @jkseppan? @mdboom - any ideas?

Michael Droettboom
Owner

This looks fine to me.

Phil Elson
Collaborator

Is there any documentation needed for this change? Is the ps.usedistiller == False new functionality?

Michael Droettboom
Owner

I don't think it's new functionality, only that it will now write directly to a file, rather than to a temporary and then moved. I suppose if someone was relying on the old behavior that may be a problem -- but this change I think ultimately makes things less surprising.

Matt Giuca backend_ps: Do not write to a temporary file unless using an external…
… distiller.

If ps.usedistiller is omitted, writes directly to the output file, instead of
creating a temporary file and subsequently copying it to the output.

This is more efficient, and also works on restricted platforms such as Google
App Engine, which are unable to provide a writable temporary file system.
8d224d3
Matt Giuca

To clarify, you cannot write "ps.usedistiller = False" in the matplotlibrc. When I said "is False", I meant if the Python variable is False, which it is if ps.usedistiller is omitted from the matplotlibrc. I have changed the Git commit message to clarify.

I don't see how someone could be broken by this change. There is no noticeable difference between the old and new behaviour unless you are watching the temporary directory for files being written and quickly deleted. As far as I can tell, the only difference is that it works even if there is no writable temporary directory.

Michael Droettboom
Owner

I was thinking more about a difference caused by using a stream vs. a random access file handle. (We've had similar issues with the PDF backend). But it seems that the postscript backend doesn't exhibit such problems. I think this is good to go.

Michael Droettboom mdboom merged commit 4703f2f into from March 19, 2013
Michael Droettboom mdboom closed this March 19, 2013
Matt Giuca mgiuca-google deleted the branch March 20, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Mar 19, 2013
Matt Giuca backend_ps: Do not write to a temporary file unless using an external…
… distiller.

If ps.usedistiller is omitted, writes directly to the output file, instead of
creating a temporary file and subsequently copying it to the output.

This is more efficient, and also works on restricted platforms such as Google
App Engine, which are unable to provide a writable temporary file system.
8d224d3
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 30 additions and 15 deletions. Show diff stats Hide diff stats

  1. 45  lib/matplotlib/backends/backend_ps.py
45  lib/matplotlib/backends/backend_ps.py
@@ -5,6 +5,7 @@
5 5
 # PY3KTODO: Get rid of "print >>fh" syntax
6 6
 
7 7
 from __future__ import division, print_function
  8
+import contextlib
8 9
 import glob, math, os, shutil, sys, time
9 10
 def _fn_name(): return sys._getframe(1).f_code.co_name
10 11
 import io
@@ -1105,8 +1106,21 @@ def write(self, *kl, **kwargs):
1105 1106
         self.figure.set_facecolor(origfacecolor)
1106 1107
         self.figure.set_edgecolor(origedgecolor)
1107 1108
 
1108  
-        fd, tmpfile = mkstemp()
1109  
-        with io.open(fd, 'wb') as raw_fh:
  1109
+        if rcParams['ps.usedistiller']:
  1110
+            # We are going to use an external program to process the output.
  1111
+            # Write to a temporary file.
  1112
+            fd, tmpfile = mkstemp()
  1113
+            context_manager = io.open(fd, 'wb')
  1114
+        else:
  1115
+            # Write directly to outfile.
  1116
+            if passed_in_file_object:
  1117
+                @contextlib.contextmanager
  1118
+                def null_context(value):
  1119
+                    yield value
  1120
+                context_manager = null_context(outfile)
  1121
+            else:
  1122
+                context_manager = open(outfile, 'wb')
  1123
+        with context_manager as raw_fh:
1110 1124
             if sys.version_info[0] >= 3:
1111 1125
                 fh = io.TextIOWrapper(raw_fh, encoding="ascii")
1112 1126
             else:
@@ -1181,20 +1195,21 @@ def write(self, *kl, **kwargs):
1181 1195
             if not isEPSF: print("%%EOF", file=fh)
1182 1196
             fh.flush()
1183 1197
 
1184  
-        if rcParams['ps.usedistiller'] == 'ghostscript':
1185  
-            gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
1186  
-        elif rcParams['ps.usedistiller'] == 'xpdf':
1187  
-            xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
  1198
+        if rcParams['ps.usedistiller']:
  1199
+            if rcParams['ps.usedistiller'] == 'ghostscript':
  1200
+                gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
  1201
+            elif rcParams['ps.usedistiller'] == 'xpdf':
  1202
+                xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
1188 1203
 
1189  
-        if passed_in_file_object:
1190  
-            with open(tmpfile, 'rb') as fh:
1191  
-                outfile.write(fh.read())
1192  
-        else:
1193  
-            with open(outfile, 'w') as fh:
1194  
-                pass
1195  
-            mode = os.stat(outfile).st_mode
1196  
-            shutil.move(tmpfile, outfile)
1197  
-            os.chmod(outfile, mode)
  1204
+            if passed_in_file_object:
  1205
+                with open(tmpfile, 'rb') as fh:
  1206
+                    outfile.write(fh.read())
  1207
+            else:
  1208
+                with open(outfile, 'w') as fh:
  1209
+                    pass
  1210
+                mode = os.stat(outfile).st_mode
  1211
+                shutil.move(tmpfile, outfile)
  1212
+                os.chmod(outfile, mode)
1198 1213
 
1199 1214
     def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor,
1200 1215
                           orientation, isLandscape, papertype,
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.