diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 7de3f83b7f7d..4c4500aebeeb 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -179,8 +179,10 @@ def _is_writable_dir(p): except TypeError: return False try: t = tempfile.TemporaryFile(dir=p) - t.write('1') - t.close() + try: + t.write('1') + finally: + t.close() except OSError: return False else: return True @@ -698,21 +700,25 @@ def rc_params(fail_on_error=False): cnt = 0 rc_temp = {} - for line in file(fname): - cnt += 1 - strippedline = line.split('#',1)[0].strip() - if not strippedline: continue - tup = strippedline.split(':',1) - if len(tup) !=2: - warnings.warn('Illegal line #%d\n\t%s\n\tin file "%s"'%\ - (cnt, line, fname)) - continue - key, val = tup - key = key.strip() - val = val.strip() - if key in rc_temp: - warnings.warn('Duplicate key in file "%s", line #%d'%(fname,cnt)) - rc_temp[key] = (val, line, cnt) + fd = open(fname) + try: + for line in fd: + cnt += 1 + strippedline = line.split('#',1)[0].strip() + if not strippedline: continue + tup = strippedline.split(':',1) + if len(tup) !=2: + warnings.warn('Illegal line #%d\n\t%s\n\tin file "%s"'%\ + (cnt, line, fname)) + continue + key, val = tup + key = key.strip() + val = val.strip() + if key in rc_temp: + warnings.warn('Duplicate key in file "%s", line #%d'%(fname,cnt)) + rc_temp[key] = (val, line, cnt) + finally: + fd.close() ret = RcParams([ (key, default) for key, (default, converter) in \ defaultParams.iteritems() ]) diff --git a/lib/matplotlib/afm.py b/lib/matplotlib/afm.py index bb5163453170..ccf7e9c83aca 100644 --- a/lib/matplotlib/afm.py +++ b/lib/matplotlib/afm.py @@ -500,5 +500,8 @@ def get_vertical_stem_width(self): for fname in os.listdir(pathname): fh = file(os.path.join(pathname,fname)) - afm = AFM(fh) - w,h = afm.string_width_height('John Hunter is the Man!') + try: + afm = AFM(fh) + w,h = afm.string_width_height('John Hunter is the Man!') + finally: + fh.close() diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index 03331f5ed22d..da74ac2d0bb2 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -82,7 +82,7 @@ def draw_markers(self, *kl, **kw): def draw_path_collection(self, *kl, **kw): return self._renderer.draw_path_collection(*kl, **kw) - + def _update_methods(self): #self.draw_path = self._renderer.draw_path # see below #self.draw_markers = self._renderer.draw_markers @@ -437,7 +437,14 @@ def print_raw(self, filename_or_obj, *args, **kwargs): renderer.dpi = self.figure.dpi if is_string_like(filename_or_obj): filename_or_obj = file(filename_or_obj, 'wb') - renderer._renderer.write_rgba(filename_or_obj) + close = True + else: + close = False + try: + renderer._renderer.write_rgba(filename_or_obj) + finally: + if close: + filename_or_obj.close() renderer.dpi = original_dpi print_rgba = print_raw @@ -448,9 +455,16 @@ def print_png(self, filename_or_obj, *args, **kwargs): renderer.dpi = self.figure.dpi if is_string_like(filename_or_obj): filename_or_obj = file(filename_or_obj, 'wb') - _png.write_png(renderer._renderer.buffer_rgba(0, 0), - renderer.width, renderer.height, - filename_or_obj, self.figure.dpi) + close = True + else: + close = False + try: + _png.write_png(renderer._renderer.buffer_rgba(0, 0), + renderer.width, renderer.height, + filename_or_obj, self.figure.dpi) + finally: + if close: + filename_or_obj.close() renderer.dpi = original_dpi def print_to_buffer(self): diff --git a/lib/matplotlib/backends/backend_cairo.py b/lib/matplotlib/backends/backend_cairo.py index f8510edd6097..095eece524bd 100644 --- a/lib/matplotlib/backends/backend_cairo.py +++ b/lib/matplotlib/backends/backend_cairo.py @@ -461,7 +461,14 @@ def _save (self, fo, format, **kwargs): filename = fo if is_string_like(fo): fo = open(fo, 'wb') - fo = gzip.GzipFile(None, 'wb', fileobj=fo) + close = True + else: + close = False + try: + fo = gzip.GzipFile(None, 'wb', fileobj=fo) + finally: + if close: + fo.close() surface = cairo.SVGSurface (fo, width_in_points, height_in_points) else: warnings.warn ("unknown format: %s" % format) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index a3aa62a2a15e..8d101648f1ae 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -565,8 +565,10 @@ def writeFonts(self): def _write_afm_font(self, filename): fh = file(filename) - font = AFM(fh) - fh.close() + try: + font = AFM(fh) + finally: + fh.close() fontname = font.get_fontname() fontdict = { 'Type': Name('Font'), 'Subtype': Name('Type1'), @@ -876,14 +878,13 @@ def embedTTFType42(font, characters, descriptor): fontfileObject.id, self.reserveObject('length of font stream'), {'Length1': length1Object}) - fontfile = open(filename, 'rb') - length1 = 0 - while True: - data = fontfile.read(4096) - if not data: break - length1 += len(data) - self.currentstream.write(data) - fontfile.close() + with open(filename, 'rb') as fontfile: + length1 = 0 + while True: + data = fontfile.read(4096) + if not data: break + length1 += len(data) + self.currentstream.write(data) self.endStream() self.writeObject(length1Object, length1) @@ -1831,9 +1832,11 @@ def _get_font_afm(self, prop): font = self.afm_font_cache.get(filename) if font is None: fh = file(filename) - font = AFM(fh) - self.afm_font_cache[filename] = font - fh.close() + try: + font = AFM(fh) + self.afm_font_cache[filename] = font + finally: + fh.close() self.afm_font_cache[key] = font return font @@ -2178,17 +2181,19 @@ def print_pdf(self, filename, **kwargs): file = filename._file else: file = PdfFile(filename) - file.newPage(width, height) - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) - renderer = MixedModeRenderer(self.figure, - width, height, image_dpi, RendererPdf(file, image_dpi), - bbox_inches_restore=_bbox_inches_restore) - self.figure.draw(renderer) - renderer.finalize() - if isinstance(filename, PdfPages): # finish off this page - file.endStream() - else: # we opened the file above; now finish it off - file.close() + try: + file.newPage(width, height) + _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) + renderer = MixedModeRenderer(self.figure, + width, height, image_dpi, RendererPdf(file, image_dpi), + bbox_inches_restore=_bbox_inches_restore) + self.figure.draw(renderer) + renderer.finalize() + finally: + if isinstance(filename, PdfPages): # finish off this page + file.endStream() + else: # we opened the file above; now finish it off + file.close() class FigureManagerPdf(FigureManagerBase): pass diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index dfadb52cfd03..4663374e91b5 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -371,7 +371,11 @@ def _get_font_afm(self, prop): "Helvetica", fontext='afm', directory=self._afm_font_dir) font = self.afmfontd.get(fname) if font is None: - font = AFM(file(fname)) + fh = file(fname) + try: + font = AFM(fh) + finally: + fh.close() self.afmfontd[fname] = font self.afmfontd[key] = font return font @@ -1012,9 +1016,6 @@ def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w', else: raise ValueError("outfile must be a path or a file-like object") - fd, tmpfile = mkstemp() - fh = os.fdopen(fd, 'w') - # find the appropriate papertype width, height = self.figure.get_size_inches() if papertype == 'auto': @@ -1085,73 +1086,78 @@ def write(self, *kl, **kwargs): self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) - # write the PostScript headers - if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" - else: print >>fh, "%!PS-Adobe-3.0" - if title: print >>fh, "%%Title: "+title - print >>fh, ("%%Creator: matplotlib version " - +__version__+", http://matplotlib.sourceforge.net/") - print >>fh, "%%CreationDate: "+time.ctime(time.time()) - print >>fh, "%%Orientation: " + orientation - if not isEPSF: print >>fh, "%%DocumentPaperSizes: "+papertype - print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox - if not isEPSF: print >>fh, "%%Pages: 1" - print >>fh, "%%EndComments" - - Ndict = len(psDefs) - print >>fh, "%%BeginProlog" - if not rcParams['ps.useafm']: - Ndict += len(ps_renderer.used_characters) - print >>fh, "/mpldict %d dict def"%Ndict - print >>fh, "mpldict begin" - for d in psDefs: - d=d.strip() - for l in d.split('\n'): - print >>fh, l.strip() - if not rcParams['ps.useafm']: - for font_filename, chars in ps_renderer.used_characters.values(): - if len(chars): - font = FT2Font(str(font_filename)) - cmap = font.get_charmap() - glyph_ids = [] - for c in chars: - gind = cmap.get(c) or 0 - glyph_ids.append(gind) - - fonttype = rcParams['ps.fonttype'] - - # Can not use more than 255 characters from a - # single font for Type 3 - if len(glyph_ids) > 255: - fonttype = 42 - - # The ttf to ps (subsetting) support doesn't work for - # OpenType fonts that are Postscript inside (like the - # STIX fonts). This will simply turn that off to avoid - # errors. - if is_opentype_cff_font(font_filename): - raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.") - else: - convert_ttf_to_ps(font_filename, fh, fonttype, glyph_ids) - print >>fh, "end" - print >>fh, "%%EndProlog" - - if not isEPSF: print >>fh, "%%Page: 1 1" - print >>fh, "mpldict begin" - #print >>fh, "gsave" - print >>fh, "%s translate"%_nums_to_str(xo, yo) - if rotation: print >>fh, "%d rotate"%rotation - print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0) - - # write the figure - print >>fh, self._pswriter.getvalue() - - # write the trailer - #print >>fh, "grestore" - print >>fh, "end" - print >>fh, "showpage" - if not isEPSF: print >>fh, "%%EOF" - fh.close() + fd, tmpfile = mkstemp() + fh = open(fd, 'wb') + + try: + # write the PostScript headers + if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" + else: print >>fh, "%!PS-Adobe-3.0" + if title: print >>fh, "%%Title: "+title + print >>fh, ("%%Creator: matplotlib version " + +__version__+", http://matplotlib.sourceforge.net/") + print >>fh, "%%CreationDate: "+time.ctime(time.time()) + print >>fh, "%%Orientation: " + orientation + if not isEPSF: print >>fh, "%%DocumentPaperSizes: "+papertype + print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox + if not isEPSF: print >>fh, "%%Pages: 1" + print >>fh, "%%EndComments" + + Ndict = len(psDefs) + print >>fh, "%%BeginProlog" + if not rcParams['ps.useafm']: + Ndict += len(ps_renderer.used_characters) + print >>fh, "/mpldict %d dict def"%Ndict + print >>fh, "mpldict begin" + for d in psDefs: + d=d.strip() + for l in d.split('\n'): + print >>fh, l.strip() + if not rcParams['ps.useafm']: + for font_filename, chars in ps_renderer.used_characters.values(): + if len(chars): + font = FT2Font(str(font_filename)) + cmap = font.get_charmap() + glyph_ids = [] + for c in chars: + gind = cmap.get(c) or 0 + glyph_ids.append(gind) + + fonttype = rcParams['ps.fonttype'] + + # Can not use more than 255 characters from a + # single font for Type 3 + if len(glyph_ids) > 255: + fonttype = 42 + + # The ttf to ps (subsetting) support doesn't work for + # OpenType fonts that are Postscript inside (like the + # STIX fonts). This will simply turn that off to avoid + # errors. + if is_opentype_cff_font(font_filename): + raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.") + else: + convert_ttf_to_ps(font_filename, fh, fonttype, glyph_ids) + print >>fh, "end" + print >>fh, "%%EndProlog" + + if not isEPSF: print >>fh, "%%Page: 1 1" + print >>fh, "mpldict begin" + #print >>fh, "gsave" + print >>fh, "%s translate"%_nums_to_str(xo, yo) + if rotation: print >>fh, "%d rotate"%rotation + print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0) + + # write the figure + print >>fh, self._pswriter.getvalue() + + # write the trailer + #print >>fh, "grestore" + print >>fh, "end" + print >>fh, "showpage" + if not isEPSF: print >>fh, "%%EOF" + finally: + fh.close() if rcParams['ps.usedistiller'] == 'ghostscript': gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox) @@ -1160,9 +1166,13 @@ def write(self, *kl, **kwargs): if passed_in_file_object: fh = open(tmpfile) - print >>outfile, fh.read() + try: + print >>outfile, fh.read() + finally: + fh.close() else: - open(outfile, 'w') + with open(outfile, 'w') as fh: + pass mode = os.stat(outfile).st_mode shutil.move(tmpfile, outfile) os.chmod(outfile, mode) @@ -1178,10 +1188,6 @@ def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor, isEPSF = format == 'eps' title = outfile - # write to a temp file, we'll move it to outfile when done - fd, tmpfile = mkstemp() - fh = os.fdopen(fd, 'w') - self.figure.dpi = 72 # ignore the dpi kwarg width, height = self.figure.get_size_inches() xo = 0 @@ -1227,39 +1233,44 @@ def write(self, *kl, **kwargs): self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) - # write the Encapsulated PostScript headers - print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" - if title: print >>fh, "%%Title: "+title - print >>fh, ("%%Creator: matplotlib version " - +__version__+", http://matplotlib.sourceforge.net/") - print >>fh, "%%CreationDate: "+time.ctime(time.time()) - print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox - print >>fh, "%%EndComments" - - Ndict = len(psDefs) - print >>fh, "%%BeginProlog" - print >>fh, "/mpldict %d dict def"%Ndict - print >>fh, "mpldict begin" - for d in psDefs: - d=d.strip() - for l in d.split('\n'): - print >>fh, l.strip() - print >>fh, "end" - print >>fh, "%%EndProlog" - - print >>fh, "mpldict begin" - #print >>fh, "gsave" - print >>fh, "%s translate"%_nums_to_str(xo, yo) - print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0) - - # write the figure - print >>fh, self._pswriter.getvalue() - - # write the trailer - #print >>fh, "grestore" - print >>fh, "end" - print >>fh, "showpage" - fh.close() + fd, tmpfile = mkstemp() + fh = os.fdopen(fd, 'w') + + try: + # write the Encapsulated PostScript headers + print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" + if title: print >>fh, "%%Title: "+title + print >>fh, ("%%Creator: matplotlib version " + +__version__+", http://matplotlib.sourceforge.net/") + print >>fh, "%%CreationDate: "+time.ctime(time.time()) + print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox + print >>fh, "%%EndComments" + + Ndict = len(psDefs) + print >>fh, "%%BeginProlog" + print >>fh, "/mpldict %d dict def"%Ndict + print >>fh, "mpldict begin" + for d in psDefs: + d=d.strip() + for l in d.split('\n'): + print >>fh, l.strip() + print >>fh, "end" + print >>fh, "%%EndProlog" + + print >>fh, "mpldict begin" + #print >>fh, "gsave" + print >>fh, "%s translate"%_nums_to_str(xo, yo) + print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0) + + # write the figure + print >>fh, self._pswriter.getvalue() + + # write the trailer + #print >>fh, "grestore" + print >>fh, "end" + print >>fh, "showpage" + finally: + fh.close() if isLandscape: # now we are ready to rotate isLandscape = True @@ -1308,9 +1319,13 @@ def write(self, *kl, **kwargs): if isinstance(outfile, file): fh = file(tmpfile) - print >>outfile, fh.read() + try: + print >>outfile, fh.read() + finally: + fh.close() else: - open(outfile, 'w') + fh = open(outfile, 'w') + fh.close() mode = os.stat(outfile).st_mode shutil.move(tmpfile, outfile) os.chmod(outfile, mode) @@ -1329,7 +1344,6 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, shutil.move(tmpfile, epsfile) latexfile = tmpfile+'.tex' outfile = tmpfile+'.output' - latexh = file(latexfile, 'w') dvifile = tmpfile+'.dvi' psfile = tmpfile+'.ps' @@ -1363,18 +1377,20 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, paperWidth, paperHeight, '\n'.join(psfrags), angle, os.path.split(epsfile)[-1]) - if rcParams['text.latex.unicode']: - latexh.write(s.encode('utf8')) - else: - try: - latexh.write(s) - except UnicodeEncodeError, err: - verbose.report("You are using unicode and latex, but have " - "not enabled the matplotlib 'text.latex.unicode' " - "rcParam.", 'helpful') - raise - - latexh.close() + latexh = file(latexfile, 'w') + try: + if rcParams['text.latex.unicode']: + latexh.write(s.encode('utf8')) + else: + try: + latexh.write(s) + except UnicodeEncodeError, err: + verbose.report("You are using unicode and latex, but have " + "not enabled the matplotlib 'text.latex.unicode' " + "rcParam.", 'helpful') + raise + finally: + latexh.close() # the split drive part of the command is necessary for windows users with # multiple @@ -1385,23 +1401,28 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, verbose.report(command, 'debug') exit_status = os.system(command) fh = file(outfile) - if exit_status: - raise RuntimeError('LaTeX was not able to process your file:\ + try: + 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: verbose.report(fh.read(), 'debug') - fh.close() + else: verbose.report(fh.read(), 'debug') + finally: + fh.close() 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) + fh = file(outfile) - 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: verbose.report(fh.read(), 'debug') - fh.close() + try: + 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: verbose.report(fh.read(), 'debug') + finally: + fh.close() os.remove(outfile) os.remove(epsfile) shutil.move(psfile, tmpfile) @@ -1413,10 +1434,11 @@ def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble, # the generated ps file is in landscape and return this # information. The return value is used in pstoeps step to recover # the correct bounding box. 2010-06-05 JJL - if "Landscape" in open(tmpfile).read(1000): - psfrag_rotated = True - else: - psfrag_rotated = False + with open(tmpfile) as fh: + if "Landscape" in fh.read(1000): + psfrag_rotated = True + else: + psfrag_rotated = False if not debugPS: for fname in glob.glob(tmpfile+'.*'): @@ -1452,10 +1474,12 @@ def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): verbose.report(command, 'debug') exit_status = os.system(command) fh = file(outfile) - if exit_status: raise RuntimeError('ghostscript was not able to process \ -your image.\nHere is the full report generated by ghostscript:\n\n' + fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + try: + if exit_status: raise RuntimeError('ghostscript was not able to process \ + your image.\nHere is the full report generated by ghostscript:\n\n' + fh.read()) + else: verbose.report(fh.read(), 'debug') + finally: + fh.close() os.remove(outfile) os.remove(tmpfile) shutil.move(psfile, tmpfile) @@ -1497,20 +1521,26 @@ def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False): verbose.report(command, 'debug') exit_status = os.system(command) fh = file(outfile) - if exit_status: raise RuntimeError('ps2pdf was not able to process your \ + try: + if exit_status: raise RuntimeError('ps2pdf was not able to process your \ image.\n\Here is the report generated by ghostscript:\n\n' + fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + else: + verbose.report(fh.read(), 'debug') + finally: + fh.close() os.remove(outfile) command = 'pdftops -paper match -level2 "%s" "%s" > "%s"'% \ (pdffile, psfile, outfile) verbose.report(command, 'debug') exit_status = os.system(command) fh = file(outfile) - if exit_status: raise RuntimeError('pdftops was not able to process your \ + try: + 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: verbose.report(fh.read(), 'debug') - fh.close() + else: + verbose.report(fh.read(), 'debug') + finally: + fh.close() os.remove(outfile) os.remove(tmpfile) shutil.move(psfile, tmpfile) @@ -1598,59 +1628,55 @@ def pstoeps(tmpfile, bbox=None, rotated=False): epsfile = tmpfile + '.eps' epsh = file(epsfile, 'w') - tmph = file(tmpfile) - line = tmph.readline() - # Modify the header: - while line: - if line.startswith('%!PS'): - print >>epsh, "%!PS-Adobe-3.0 EPSF-3.0" - if bbox: - print >>epsh, bbox_info - elif line.startswith('%%EndComments'): - epsh.write(line) - print >>epsh, '%%BeginProlog' - print >>epsh, 'save' - print >>epsh, 'countdictstack' - print >>epsh, 'mark' - print >>epsh, 'newpath' - print >>epsh, '/showpage {} def' - print >>epsh, '/setpagedevice {pop} def' - print >>epsh, '%%EndProlog' - print >>epsh, '%%Page 1 1' - if rotate: - print >>epsh, rotate - break - elif bbox and (line.startswith('%%Bound') \ - or line.startswith('%%HiResBound') \ - or line.startswith('%%DocumentMedia') \ - or line.startswith('%%Pages')): - pass - else: - epsh.write(line) + try: line = tmph.readline() - # Now rewrite the rest of the file, and modify the trailer. - # This is done in a second loop such that the header of the embedded - # eps file is not modified. - line = tmph.readline() - while line: - if line.startswith('%%Trailer'): - print >>epsh, '%%Trailer' - print >>epsh, 'cleartomark' - print >>epsh, 'countdictstack' - print >>epsh, 'exch sub { end } repeat' - print >>epsh, 'restore' - if rcParams['ps.usedistiller'] == 'xpdf': - # remove extraneous "end" operator: - line = tmph.readline() - elif line.startswith('%%PageBoundingBox'): - pass - else: - epsh.write(line) + # Modify the header: + while line: + if line.startswith('%!PS'): + print >>epsh, "%!PS-Adobe-3.0 EPSF-3.0" + if bbox: + print >>epsh, bbox_info + elif line.startswith('%%EndComments'): + epsh.write(line) + print >>epsh, '%%BeginProlog' + print >>epsh, 'save' + print >>epsh, 'countdictstack' + print >>epsh, 'mark' + print >>epsh, 'newpath' + print >>epsh, '/showpage {} def' + print >>epsh, '/setpagedevice {pop} def' + print >>epsh, '%%EndProlog' + print >>epsh, '%%Page 1 1' + if rotate: + print >>epsh, rotate + break + elif bbox and (line.startswith('%%Bound') \ + or line.startswith('%%HiResBound') \ + or line.startswith('%%DocumentMedia') \ + or line.startswith('%%Pages')): + pass + else: + epsh.write(line) + line = tmph.readline() + # Now rewrite the rest of the file, and modify the trailer. + # This is done in a second loop such that the header of the embedded + # eps file is not modified. line = tmph.readline() + while line: + if line.startswith('%%Trailer'): + print >>epsh, '%%Trailer' + print >>epsh, 'cleartomark' + print >>epsh, 'countdictstack' + print >>epsh, 'exch sub { end } repeat' + print >>epsh, 'restore' + if rcParams['ps.usedistiller'] == 'xpdf': + # remove extraneous "end" operator: + line = tmph.readline() + finally: + epsh.close() + tmph.close() - tmph.close() - epsh.close() os.remove(tmpfile) shutil.move(epsfile, tmpfile) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 25b92390cb37..ebe5ebd3b227 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -1087,31 +1087,33 @@ def print_svgz(self, filename, *args, **kwargs): return self._print_svg(filename, svgwriter, fh_to_close) def _print_svg(self, filename, svgwriter, fh_to_close=None, **kwargs): - self.figure.set_dpi(72.0) - width, height = self.figure.get_size_inches() - w, h = width*72, height*72 + try: + self.figure.set_dpi(72.0) + width, height = self.figure.get_size_inches() + w, h = width*72, height*72 - if rcParams['svg.image_noscale']: - renderer = RendererSVG(w, h, svgwriter, filename) - else: - # setting mixed renderer dpi other than 72 results in - # incorrect size of the rasterized image. It seems that the - # svg internally uses fixed dpi of 72 and seems to cause - # the problem. I hope someone who knows the svg backends - # take a look at this problem. Meanwhile, the dpi - # parameter is ignored and image_dpi is fixed at 72. - JJL - - #image_dpi = kwargs.pop("dpi", 72) - image_dpi = 72 - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) - renderer = MixedModeRenderer(self.figure, - width, height, image_dpi, RendererSVG(w, h, svgwriter, filename), - bbox_inches_restore=_bbox_inches_restore) - - self.figure.draw(renderer) - renderer.finalize() - if fh_to_close is not None: - svgwriter.close() + if rcParams['svg.image_noscale']: + renderer = RendererSVG(w, h, svgwriter, filename) + else: + # setting mixed renderer dpi other than 72 results in + # incorrect size of the rasterized image. It seems that the + # svg internally uses fixed dpi of 72 and seems to cause + # the problem. I hope someone who knows the svg backends + # take a look at this problem. Meanwhile, the dpi + # parameter is ignored and image_dpi is fixed at 72. - JJL + + #image_dpi = kwargs.pop("dpi", 72) + image_dpi = 72 + _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) + renderer = MixedModeRenderer(self.figure, + width, height, image_dpi, RendererSVG(w, h, svgwriter, filename), + bbox_inches_restore=_bbox_inches_restore) + + self.figure.draw(renderer) + renderer.finalize() + finally: + if fh_to_close is not None: + svgwriter.close() def get_default_filetype(self): return 'svg' diff --git a/lib/matplotlib/cbook.py b/lib/matplotlib/cbook.py index 58f14e4322af..de95ace2dc48 100644 --- a/lib/matplotlib/cbook.py +++ b/lib/matplotlib/cbook.py @@ -481,8 +481,10 @@ def read_cache(self): return f = open(fn, 'rb') - cache = cPickle.load(f) - f.close() + try: + cache = cPickle.load(f) + finally: + f.close() # Earlier versions did not have the full paths in cache.pck for url, (fn, x, y) in cache.items(): @@ -526,8 +528,10 @@ def write_cache(self): """ fn = self.in_cache_dir('cache.pck') f = open(fn, 'wb') - cPickle.dump(self.cache, f, -1) - f.close() + try: + cPickle.dump(self.cache, f, -1) + finally: + f.close() def cache_file(self, url, data, headers): """ @@ -538,8 +542,10 @@ def cache_file(self, url, data, headers): fullpath = self.in_cache_dir(fn) f = open(fullpath, 'wb') - f.write(data) - f.close() + try: + f.write(data) + finally: + f.close() # Update the cache self.cache[url] = (fullpath, headers.get('ETag'), @@ -577,7 +583,10 @@ def https_error_304(self, req, fp, code, msg, hdrs): 'ViewVCCachedServer: reading data file from cache file "%s"' %fn, 'debug') file = open(fn, 'rb') - handle = urllib2.addinfourl(file, hdrs, url) + try: + handle = urllib2.addinfourl(file, hdrs, url) + except: + file.close() handle.code = 304 return handle diff --git a/lib/matplotlib/dviread.py b/lib/matplotlib/dviread.py index 8a6dbd264b1f..facfa846f1ac 100644 --- a/lib/matplotlib/dviread.py +++ b/lib/matplotlib/dviread.py @@ -391,22 +391,22 @@ class DviFont(object): The size is in Adobe points (converted from TeX points). .. attribute:: texname - + Name of the font as used internally by TeX and friends. This is usually very different from any external font names, and :class:`dviread.PsfontsMap` can be used to find the external name of the font. .. attribute:: size - + Size of the font in Adobe points, converted from the slightly smaller TeX points. .. attribute:: widths - + Widths of glyphs in glyph-space units, typically 1/1000ths of the point size. - + """ __slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm') @@ -459,7 +459,7 @@ def _height_depth_of(self, char): else: result.append(_mul2012(value, self._scale)) return result - + class Vf(Dvi): """ A virtual font (\*.vf file) containing subroutines for dvi files. @@ -473,11 +473,13 @@ class Vf(Dvi): def __init__(self, filename): Dvi.__init__(self, filename, 0) - self._first_font = None - self._chars = {} - self._packet_ends = None - self._read() - self.close() + try: + self._first_font = None + self._chars = {} + self._packet_ends = None + self._read() + finally: + self.close() def __getitem__(self, code): return self._chars[code] @@ -586,18 +588,16 @@ class Tfm(object): .. attribute:: height Height of each character. - + .. attribute:: depth - + Depth of each character. """ __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth') def __init__(self, filename): matplotlib.verbose.report('opening tfm file ' + filename, 'debug') - file = open(filename, 'rb') - - try: + with open(filename, 'rb') as file: header1 = file.read(24) lh, bc, ec, nw, nh, nd = \ struct.unpack('!6H', header1[2:14]) @@ -612,8 +612,6 @@ def __init__(self, filename): widths = file.read(4*nw) heights = file.read(4*nh) depths = file.read(4*nd) - finally: - file.close() self.width, self.height, self.depth = {}, {}, {} widths, heights, depths = \ @@ -663,11 +661,8 @@ class PsfontsMap(object): def __init__(self, filename): self._font = {} - file = open(filename, 'rt') - try: + with open(filename, 'rt') as file: self._parse(file) - finally: - file.close() def __getitem__(self, texname): result = self._font[texname] @@ -832,7 +827,7 @@ def find_tex_file(filename, format=None): if format is not None: cmd += ['--format=' + format] cmd += [filename] - + matplotlib.verbose.report('find_tex_file(%s): %s' \ % (filename,cmd), 'debug') # stderr is unused, but reading it avoids a subprocess optimization diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 52f894bdf93c..21ad46c8afb9 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -1187,9 +1187,14 @@ def pilread(): # reader extension, since Python handles them quite well, but it's # tricky in C. if cbook.is_string_like(fname): - fname = open(fname, 'rb') - - return handler(fname) + fd = open(fname, 'rb') + try: + result = handler(fd) + finally: + fd.close() + return result + else: + return handler(fname) def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, diff --git a/lib/matplotlib/mathtext.py b/lib/matplotlib/mathtext.py index 0cb277da5838..61e4fcf653e9 100644 --- a/lib/matplotlib/mathtext.py +++ b/lib/matplotlib/mathtext.py @@ -1051,7 +1051,11 @@ def __init__(self, default_font_prop): if filename is None: filename = findfont('Helvetica', fontext='afm', directory=self.basepath) - default_font = AFM(file(filename, 'r')) + fd = file(filename, 'r') + try: + default_font = AFM(fd) + finally: + fd.close() default_font.fname = filename self.fonts['default'] = default_font @@ -1067,7 +1071,11 @@ def _get_font(self, font): cached_font = self.fonts.get(basename) if cached_font is None: fname = os.path.join(self.basepath, basename + ".afm") - cached_font = AFM(file(fname, 'r')) + fd = file(fname, 'r') + try: + cached_font = AFM(fd) + finally: + fd.close() cached_font.fname = fname self.fonts[basename] = cached_font self.fonts[cached_font.get_fontname()] = cached_font diff --git a/lib/matplotlib/sphinxext/plot_directive.py b/lib/matplotlib/sphinxext/plot_directive.py index 5d7b2c524b72..02b8836cb635 100644 --- a/lib/matplotlib/sphinxext/plot_directive.py +++ b/lib/matplotlib/sphinxext/plot_directive.py @@ -624,9 +624,8 @@ def run(arguments, content, options, state_machine, state, lineno): else: function_name = None - fd = open(source_file_name, 'r') - code = fd.read() - fd.close() + with open(source_file_name, 'r') as fd: + code = fd.read() output_base = os.path.basename(source_file_name) else: source_file_name = rst_file @@ -765,12 +764,14 @@ def run(arguments, content, options, state_machine, state, lineno): # copy script (if necessary) target_name = os.path.join(dest_dir, output_base + source_ext) - f = open(target_name, 'w') if source_file_name == rst_file: code_escaped = unescape_doctest(code) else: code_escaped = code - f.write(code_escaped) - f.close() + f = open(target_name, 'w') + try: + f.write(code_escaped) + finally: + f.close() return errors diff --git a/lib/matplotlib/texmanager.py b/lib/matplotlib/texmanager.py index 93f85f1640e6..8ac4df806e61 100644 --- a/lib/matplotlib/texmanager.py +++ b/lib/matplotlib/texmanager.py @@ -228,7 +228,6 @@ def make_tex(self, tex, fontsize): """ basefile = self.get_basefile(tex, fontsize) texfile = '%s.tex'%basefile - fh = file(texfile, 'w') custom_preamble = self.get_custom_preamble() fontcmd = {'sans-serif' : r'{\sffamily %s}', 'monospace' : r'{\ttfamily %s}'}.get(self.font_family, @@ -252,18 +251,22 @@ def make_tex(self, tex, fontsize): \end{document} """ % (self._font_preamble, unicode_preamble, custom_preamble, fontsize, fontsize*1.25, tex) - if rcParams['text.latex.unicode']: - fh.write(s.encode('utf8')) - else: - try: - fh.write(s) - except UnicodeEncodeError, err: - mpl.verbose.report("You are using unicode and latex, but have " - "not enabled the matplotlib 'text.latex.unicode' " - "rcParam.", 'helpful') - raise - fh.close() + fh = file(texfile, 'w') + + try: + if rcParams['text.latex.unicode']: + fh.write(s.encode('utf8')) + else: + try: + fh.write(s) + except UnicodeEncodeError, err: + mpl.verbose.report("You are using unicode and latex, but have " + "not enabled the matplotlib 'text.latex.unicode' " + "rcParam.", 'helpful') + raise + finally: + fh.close() return texfile @@ -280,7 +283,6 @@ def make_tex_preview(self, tex, fontsize): """ basefile = self.get_basefile(tex, fontsize) texfile = '%s.tex'%basefile - fh = file(texfile, 'w') custom_preamble = self.get_custom_preamble() fontcmd = {'sans-serif' : r'{\sffamily %s}', 'monospace' : r'{\ttfamily %s}'}.get(self.font_family, @@ -317,18 +319,22 @@ def make_tex_preview(self, tex, fontsize): \end{document} """ % (self._font_preamble, unicode_preamble, custom_preamble, fontsize, fontsize*1.25, tex) - if rcParams['text.latex.unicode']: - fh.write(s.encode('utf8')) - else: - try: - fh.write(s) - except UnicodeEncodeError, err: - mpl.verbose.report("You are using unicode and latex, but have " - "not enabled the matplotlib 'text.latex.unicode' " - "rcParam.", 'helpful') - raise - fh.close() + fh = file(texfile, 'w') + + try: + if rcParams['text.latex.unicode']: + fh.write(s.encode('utf8')) + else: + try: + fh.write(s) + except UnicodeEncodeError, err: + mpl.verbose.report("You are using unicode and latex, but have " + "not enabled the matplotlib 'text.latex.unicode' " + "rcParam.", 'helpful') + raise + finally: + fh.close() return texfile @@ -357,8 +363,10 @@ def make_dvi(self, tex, fontsize): exit_status = os.system(command) try: fh = file(outfile) - report = fh.read() - fh.close() + try: + report = fh.read() + finally: + fh.close() except IOError: report = 'No latex error report available.' try: @@ -403,8 +411,10 @@ def make_dvi_preview(self, tex, fontsize): exit_status = os.system(command) try: fh = file(outfile) - report = fh.read() - fh.close() + try: + report = fh.read() + finally: + fh.close() except IOError: report = 'No latex error report available.' @@ -416,7 +426,8 @@ 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) - open(basefile+'.baseline',"w").write(" ".join(m.groups())) + with open(basefile+'.baseline',"w") as fh: + fh.write(" ".join(m.groups())) for fname in glob.glob(basefile+'*'): if fname.endswith('dvi'): pass @@ -449,8 +460,10 @@ def make_png(self, tex, fontsize, dpi): exit_status = os.system(command) try: fh = file(outfile) - report = fh.read() - fh.close() + try: + report = fh.read() + finally: + fh.close() except IOError: report = 'No dvipng error report available.' if exit_status: @@ -482,12 +495,14 @@ def make_ps(self, tex, fontsize): mpl.verbose.report(command, 'debug') exit_status = os.system(command) fh = file(outfile) - if exit_status: - raise RuntimeError('dvipng was not able to \ + try: + if exit_status: + 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') - fh.close() + else: mpl.verbose.report(fh.read(), 'debug') + finally: + fh.close() os.remove(outfile) return psfile @@ -499,9 +514,12 @@ def get_ps_bbox(self, tex, fontsize): """ psfile = self.make_ps(tex, fontsize) ps = file(psfile) - for line in ps: - if line.startswith('%%BoundingBox:'): - return [int(val) for val in line.split()[1:]] + try: + for line in ps: + if line.startswith('%%BoundingBox:'): + return [int(val) for val in line.split()[1:]] + finally: + ps.close() raise RuntimeError('Could not parse %s'%psfile) def get_grey(self, tex, fontsize=None, dpi=None): @@ -597,7 +615,8 @@ def get_text_width_height_descent(self, tex, fontsize, renderer=None): if DEBUG or not os.path.exists(baselinefile): dvifile = self.make_dvi_preview(tex, fontsize) - l = open(baselinefile).read().split() + with open(baselinefile) as fh: + l = fh.read().split() height, depth, width = [float(l1)*dpi_fraction for l1 in l] return width, height+depth, depth @@ -605,7 +624,9 @@ def get_text_width_height_descent(self, tex, fontsize, renderer=None): # use dviread. It sometimes returns a wrong descent. dvifile = self.make_dvi(tex, fontsize) dvi = dviread.Dvi(dvifile, 72*dpi_fraction) - page = iter(dvi).next() - dvi.close() + try: + page = iter(dvi).next() + finally: + dvi.close() # A total height (including the descent) needs to be returned. return page.width, page.height+page.descent, page.descent diff --git a/lib/matplotlib/textpath.py b/lib/matplotlib/textpath.py index d27dff6a2b9a..ff1e82c19316 100644 --- a/lib/matplotlib/textpath.py +++ b/lib/matplotlib/textpath.py @@ -297,9 +297,10 @@ def get_glyphs_tex(self, prop, s, glyph_map=None, else: dvifile = texmanager.make_dvi(s, self.FONT_SCALE) dvi = dviread.Dvi(dvifile, self.DPI) - page = iter(dvi).next() - dvi.close() - + try: + page = iter(dvi).next() + finally: + dvi.close() if glyph_map is None: glyph_map = dict() diff --git a/lib/matplotlib/type1font.py b/lib/matplotlib/type1font.py index 6fad8461c78b..d21b89dba52c 100644 --- a/lib/matplotlib/type1font.py +++ b/lib/matplotlib/type1font.py @@ -58,7 +58,7 @@ def __init__(self, input): finally: file.close() self.parts = self._split(data) - + self._parse() def _read(self, file): @@ -221,9 +221,9 @@ def _parse(self): if not prop.has_key('FamilyName'): extras = r'(?i)([ -](regular|plain|italic|oblique|(semi)?bold|(ultra)?light|extra|condensed))+$' prop['FamilyName'] = re.sub(extras, '', prop['FullName']) - + self.prop = prop - + @classmethod def _transformer(cls, tokens, slant, extend): def fontname(name): @@ -272,7 +272,7 @@ def suppress(tokens): for x in itertools.takewhile(lambda x: x[1] != 'def', tokens): pass yield '' - + table = { '/FontName': replace(fontname), '/ItalicAngle': replace(italicangle), '/FontMatrix': replace(fontmatrix), @@ -285,7 +285,7 @@ def suppress(tokens): yield value else: yield value - + def transform(self, effects): """ Transform the font by slanting or extending. *effects* should @@ -297,13 +297,15 @@ def transform(self, effects): """ buffer = cStringIO.StringIO() - tokenizer = self._tokens(self.parts[0]) - for value in self._transformer(tokenizer, - slant=effects.get('slant', 0.0), - extend=effects.get('extend', 1.0)): - buffer.write(value) - result = buffer.getvalue() - buffer.close() + try: + tokenizer = self._tokens(self.parts[0]) + for value in self._transformer(tokenizer, + slant=effects.get('slant', 0.0), + extend=effects.get('extend', 1.0)): + buffer.write(value) + result = buffer.getvalue() + finally: + buffer.close() return Type1Font((result, self.parts[1], self.parts[2])) - +