Skip to content

Commit 1c9518b

Browse files
timhoffmtacaswell
authored andcommitted
Merge pull request #18679 from anntzer/pgftmpdir
Further simplify pgf tmpdir cleanup. Backports #18679 but drops the deprecation steps.
1 parent 400ea30 commit 1c9518b

File tree

1 file changed

+24
-43
lines changed

1 file changed

+24
-43
lines changed

lib/matplotlib/backends/backend_pgf.py

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import subprocess
1212
import sys
1313
import tempfile
14+
from tempfile import TemporaryDirectory
1415
import weakref
1516

1617
from PIL import Image
@@ -208,7 +209,6 @@ class LatexManager:
208209
determining the metrics of text elements. The LaTeX environment can be
209210
modified by setting fonts and/or a custom preamble in `.rcParams`.
210211
"""
211-
_unclean_instances = weakref.WeakSet()
212212

213213
@staticmethod
214214
def _build_latex_header():
@@ -245,12 +245,6 @@ def _get_cached_or_new(cls):
245245
def _get_cached_or_new_impl(cls, header): # Helper for _get_cached_or_new.
246246
return cls()
247247

248-
@staticmethod
249-
def _cleanup_remaining_instances():
250-
unclean_instances = list(LatexManager._unclean_instances)
251-
for latex_manager in unclean_instances:
252-
latex_manager._cleanup()
253-
254248
def _stdin_writeln(self, s):
255249
if self.latex is None:
256250
self._setup_latex_process()
@@ -276,13 +270,10 @@ def _expect_prompt(self):
276270
return self._expect("\n*")
277271

278272
def __init__(self):
279-
# store references for __del__
280-
self._os_path = os.path
281-
self._shutil = shutil
282-
283-
# create a tmp directory for running latex, remember to cleanup
284-
self.tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_lm_")
285-
LatexManager._unclean_instances.add(self)
273+
# create a tmp directory for running latex, register it for deletion
274+
self._tmpdir = TemporaryDirectory()
275+
self.tmpdir = self._tmpdir.name
276+
self._finalize_tmpdir = weakref.finalize(self, self._tmpdir.cleanup)
286277

287278
# test the LaTeX setup to ensure a clean startup of the subprocess
288279
self.texcommand = mpl.rcParams["pgf.texsystem"]
@@ -311,11 +302,21 @@ def __init__(self):
311302
self.str_cache = {} # cache for strings already processed
312303

313304
def _setup_latex_process(self):
314-
# open LaTeX process for real work
305+
# Open LaTeX process for real work; register it for deletion. On
306+
# Windows, we must ensure that the subprocess has quit before being
307+
# able to delete the tmpdir in which it runs; in order to do so, we
308+
# must first `kill()` it, and then `communicate()` with it.
315309
self.latex = subprocess.Popen(
316310
[self.texcommand, "-halt-on-error"],
317311
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
318312
encoding="utf-8", cwd=self.tmpdir)
313+
314+
def finalize_latex(latex):
315+
latex.kill()
316+
latex.communicate()
317+
318+
self._finalize_latex = weakref.finalize(
319+
self, finalize_latex, self.latex)
319320
# write header with 'pgf_backend_query_start' token
320321
self._stdin_writeln(self._build_latex_header())
321322
# read all lines until our 'pgf_backend_query_start' token appears
@@ -326,23 +327,6 @@ def _setup_latex_process(self):
326327
def latex_stdin_utf8(self):
327328
return self.latex.stdin
328329

329-
def _cleanup(self):
330-
if not self._os_path.isdir(self.tmpdir):
331-
return
332-
try:
333-
self.latex.communicate()
334-
except Exception:
335-
pass
336-
try:
337-
self._shutil.rmtree(self.tmpdir)
338-
LatexManager._unclean_instances.discard(self)
339-
except Exception:
340-
sys.stderr.write("error deleting tmp directory %s\n" % self.tmpdir)
341-
342-
def __del__(self):
343-
_log.debug("deleting LatexManager")
344-
self._cleanup()
345-
346330
def get_width_height_descent(self, text, prop):
347331
"""
348332
Get the width, total height and descent for a text typeset by the
@@ -779,15 +763,20 @@ class GraphicsContextPgf(GraphicsContextBase):
779763

780764

781765
class TmpDirCleaner:
782-
remaining_tmpdirs = set()
766+
_remaining_tmpdirs = set()
767+
768+
@cbook._classproperty
769+
def remaining_tmpdirs(cls):
770+
return cls._remaining_tmpdirs
783771

784772
@staticmethod
785773
def add(tmpdir):
786-
TmpDirCleaner.remaining_tmpdirs.add(tmpdir)
774+
TmpDirCleaner._remaining_tmpdirs.add(tmpdir)
787775

788776
@staticmethod
777+
@atexit.register
789778
def cleanup_remaining_tmpdirs():
790-
for tmpdir in TmpDirCleaner.remaining_tmpdirs:
779+
for tmpdir in TmpDirCleaner._remaining_tmpdirs:
791780
error_message = "error deleting tmp directory {}".format(tmpdir)
792781
shutil.rmtree(
793782
tmpdir,
@@ -979,14 +968,6 @@ class _BackendPgf(_Backend):
979968
FigureCanvas = FigureCanvasPgf
980969

981970

982-
def _cleanup_all():
983-
LatexManager._cleanup_remaining_instances()
984-
TmpDirCleaner.cleanup_remaining_tmpdirs()
985-
986-
987-
atexit.register(_cleanup_all)
988-
989-
990971
class PdfPages:
991972
"""
992973
A multi-page PDF file using the pgf backend

0 commit comments

Comments
 (0)
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