From cb7c722fb8f7e9555031b2d2074ea3e6528192c0 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Mon, 14 Dec 2020 03:02:20 +0100 Subject: [PATCH 1/4] Backport PR #19108: Fix failing animation test with pytest 6.2. --- lib/matplotlib/tests/test_image.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 6ffb2e2d0554..71c7f8e16d01 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -718,7 +718,8 @@ def test_load_from_url(): + ('///' if sys.platform == 'win32' else '') + path.resolve().as_posix()) plt.imread(url) - plt.imread(urllib.request.urlopen(url)) + with urllib.request.urlopen(url) as file: + plt.imread(file) @image_comparison(['log_scale_image'], remove_text=True) From 400ea30016ba24bc98d36f228e4461bcc2449a5c Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 16 Dec 2020 16:26:11 -0500 Subject: [PATCH 2/4] FIX: Explicitly clean up temporary files in HTMLWriter - HTMLWriter inherits from FileMovieWriter. - FileMovieWriter create a non-context manager TemporayDirectory on init. - The TemporayDirectory is cleaned up in the cleaup method of FileMovieWriter. - However this method (and its call chain through finish) try to either call a subprocess to merge a bunch of single-frame files into a movie (not relevant) or to clean up such a process (not relevant). - The least disruptive fix is to duplicate the file clean up code. --- lib/matplotlib/animation.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index 2568d455de39..472de0f8dc5b 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -891,6 +891,22 @@ def finish(self): interval=interval, **mode_dict)) + # duplicate the temporary file clean up logic from + # FileMovieWriter.cleanup. We can not call the inherited + # versions of finished or cleanup because both assume that + # there is a subprocess that we either need to call to merge + # many frames together or that there is a subprocess call that + # we need to clean up. + if self._tmpdir: + _log.debug('MovieWriter: clearing temporary path=%s', self._tmpdir) + self._tmpdir.cleanup() + else: + if self._clear_temp: + _log.debug('MovieWriter: clearing temporary paths=%s', + self._temp_paths) + for path in self._temp_paths: + path.unlink() + class Animation: """ From 1c9518b14d560cec4624132e68b6cfa1020424dd Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 8 Oct 2020 21:53:04 +0200 Subject: [PATCH 3/4] Merge pull request #18679 from anntzer/pgftmpdir Further simplify pgf tmpdir cleanup. Backports #18679 but drops the deprecation steps. --- lib/matplotlib/backends/backend_pgf.py | 67 +++++++++----------------- 1 file changed, 24 insertions(+), 43 deletions(-) diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index 8da4abca6bba..55e1b44b8501 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -11,6 +11,7 @@ import subprocess import sys import tempfile +from tempfile import TemporaryDirectory import weakref from PIL import Image @@ -208,7 +209,6 @@ class LatexManager: determining the metrics of text elements. The LaTeX environment can be modified by setting fonts and/or a custom preamble in `.rcParams`. """ - _unclean_instances = weakref.WeakSet() @staticmethod def _build_latex_header(): @@ -245,12 +245,6 @@ def _get_cached_or_new(cls): def _get_cached_or_new_impl(cls, header): # Helper for _get_cached_or_new. return cls() - @staticmethod - def _cleanup_remaining_instances(): - unclean_instances = list(LatexManager._unclean_instances) - for latex_manager in unclean_instances: - latex_manager._cleanup() - def _stdin_writeln(self, s): if self.latex is None: self._setup_latex_process() @@ -276,13 +270,10 @@ def _expect_prompt(self): return self._expect("\n*") def __init__(self): - # store references for __del__ - self._os_path = os.path - self._shutil = shutil - - # create a tmp directory for running latex, remember to cleanup - self.tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_lm_") - LatexManager._unclean_instances.add(self) + # create a tmp directory for running latex, register it for deletion + self._tmpdir = TemporaryDirectory() + self.tmpdir = self._tmpdir.name + self._finalize_tmpdir = weakref.finalize(self, self._tmpdir.cleanup) # test the LaTeX setup to ensure a clean startup of the subprocess self.texcommand = mpl.rcParams["pgf.texsystem"] @@ -311,11 +302,21 @@ def __init__(self): self.str_cache = {} # cache for strings already processed def _setup_latex_process(self): - # open LaTeX process for real work + # Open LaTeX process for real work; register it for deletion. On + # Windows, we must ensure that the subprocess has quit before being + # able to delete the tmpdir in which it runs; in order to do so, we + # must first `kill()` it, and then `communicate()` with it. self.latex = subprocess.Popen( [self.texcommand, "-halt-on-error"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding="utf-8", cwd=self.tmpdir) + + def finalize_latex(latex): + latex.kill() + latex.communicate() + + self._finalize_latex = weakref.finalize( + self, finalize_latex, self.latex) # write header with 'pgf_backend_query_start' token self._stdin_writeln(self._build_latex_header()) # read all lines until our 'pgf_backend_query_start' token appears @@ -326,23 +327,6 @@ def _setup_latex_process(self): def latex_stdin_utf8(self): return self.latex.stdin - def _cleanup(self): - if not self._os_path.isdir(self.tmpdir): - return - try: - self.latex.communicate() - except Exception: - pass - try: - self._shutil.rmtree(self.tmpdir) - LatexManager._unclean_instances.discard(self) - except Exception: - sys.stderr.write("error deleting tmp directory %s\n" % self.tmpdir) - - def __del__(self): - _log.debug("deleting LatexManager") - self._cleanup() - def get_width_height_descent(self, text, prop): """ Get the width, total height and descent for a text typeset by the @@ -779,15 +763,20 @@ class GraphicsContextPgf(GraphicsContextBase): class TmpDirCleaner: - remaining_tmpdirs = set() + _remaining_tmpdirs = set() + + @cbook._classproperty + def remaining_tmpdirs(cls): + return cls._remaining_tmpdirs @staticmethod def add(tmpdir): - TmpDirCleaner.remaining_tmpdirs.add(tmpdir) + TmpDirCleaner._remaining_tmpdirs.add(tmpdir) @staticmethod + @atexit.register def cleanup_remaining_tmpdirs(): - for tmpdir in TmpDirCleaner.remaining_tmpdirs: + for tmpdir in TmpDirCleaner._remaining_tmpdirs: error_message = "error deleting tmp directory {}".format(tmpdir) shutil.rmtree( tmpdir, @@ -979,14 +968,6 @@ class _BackendPgf(_Backend): FigureCanvas = FigureCanvasPgf -def _cleanup_all(): - LatexManager._cleanup_remaining_instances() - TmpDirCleaner.cleanup_remaining_tmpdirs() - - -atexit.register(_cleanup_all) - - class PdfPages: """ A multi-page PDF file using the pgf backend From b3ad2b9535bff52b4bb18585aedf3668b7fb4401 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 21 Dec 2020 21:44:02 -0500 Subject: [PATCH 4/4] MNT: backout a deprecation related rename --- lib/matplotlib/backends/backend_pgf.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index 55e1b44b8501..fc30e6a7b909 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -763,20 +763,16 @@ class GraphicsContextPgf(GraphicsContextBase): class TmpDirCleaner: - _remaining_tmpdirs = set() - - @cbook._classproperty - def remaining_tmpdirs(cls): - return cls._remaining_tmpdirs + remaining_tmpdirs = set() @staticmethod def add(tmpdir): - TmpDirCleaner._remaining_tmpdirs.add(tmpdir) + TmpDirCleaner.remaining_tmpdirs.add(tmpdir) @staticmethod @atexit.register def cleanup_remaining_tmpdirs(): - for tmpdir in TmpDirCleaner._remaining_tmpdirs: + for tmpdir in TmpDirCleaner.remaining_tmpdirs: error_message = "error deleting tmp directory {}".format(tmpdir) shutil.rmtree( tmpdir, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy