11
11
import shutil
12
12
import subprocess
13
13
import sys
14
- import tempfile
15
14
from tempfile import TemporaryDirectory
16
15
import weakref
17
16
@@ -200,7 +199,6 @@ class LatexManager:
200
199
determining the metrics of text elements. The LaTeX environment can be
201
200
modified by setting fonts and/or a custom preamble in `.rcParams`.
202
201
"""
203
- _unclean_instances = weakref .WeakSet ()
204
202
205
203
@staticmethod
206
204
def _build_latex_header ():
@@ -237,12 +235,6 @@ def _get_cached_or_new(cls):
237
235
def _get_cached_or_new_impl (cls , header ): # Helper for _get_cached_or_new.
238
236
return cls ()
239
237
240
- @staticmethod
241
- def _cleanup_remaining_instances ():
242
- unclean_instances = list (LatexManager ._unclean_instances )
243
- for latex_manager in unclean_instances :
244
- latex_manager ._cleanup ()
245
-
246
238
def _stdin_writeln (self , s ):
247
239
if self .latex is None :
248
240
self ._setup_latex_process ()
@@ -268,13 +260,10 @@ def _expect_prompt(self):
268
260
return self ._expect ("\n *" )
269
261
270
262
def __init__ (self ):
271
- # store references for __del__
272
- self ._os_path = os .path
273
- self ._shutil = shutil
274
-
275
- # create a tmp directory for running latex, remember to cleanup
276
- self .tmpdir = tempfile .mkdtemp (prefix = "mpl_pgf_lm_" )
277
- LatexManager ._unclean_instances .add (self )
263
+ # create a tmp directory for running latex, register it for deletion
264
+ self ._tmpdir = TemporaryDirectory ()
265
+ self .tmpdir = self ._tmpdir .name
266
+ self ._finalize_tmpdir = weakref .finalize (self , self ._tmpdir .cleanup )
278
267
279
268
# test the LaTeX setup to ensure a clean startup of the subprocess
280
269
self .texcommand = mpl .rcParams ["pgf.texsystem" ]
@@ -303,11 +292,18 @@ def __init__(self):
303
292
self .str_cache = {} # cache for strings already processed
304
293
305
294
def _setup_latex_process (self ):
306
- # open LaTeX process for real work
295
+ # Open LaTeX process for real work; register it for deletion. On
296
+ # Windows, we must ensure that the subprocess has quit before being
297
+ # able to delete the tmpdir in which it runs; in order to do so, we
298
+ # must first `kill()` it, and then `communicate()` with it, but
299
+ # finalizers are run in reverse order of creation, so the registration
300
+ # of `communicate` comes first.
307
301
self .latex = subprocess .Popen (
308
302
[self .texcommand , "-halt-on-error" ],
309
303
stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
310
304
encoding = "utf-8" , cwd = self .tmpdir )
305
+ self ._finalize_latex_1 = weakref .finalize (self , self .latex .communicate )
306
+ self ._finalize_latex_0 = weakref .finalize (self , self .latex .kill )
311
307
# write header with 'pgf_backend_query_start' token
312
308
self ._stdin_writeln (self ._build_latex_header ())
313
309
# read all lines until our 'pgf_backend_query_start' token appears
@@ -318,23 +314,6 @@ def _setup_latex_process(self):
318
314
def latex_stdin_utf8 (self ):
319
315
return self .latex .stdin
320
316
321
- def _cleanup (self ):
322
- if not self ._os_path .isdir (self .tmpdir ):
323
- return
324
- try :
325
- self .latex .communicate ()
326
- except Exception :
327
- pass
328
- try :
329
- self ._shutil .rmtree (self .tmpdir )
330
- LatexManager ._unclean_instances .discard (self )
331
- except Exception :
332
- sys .stderr .write ("error deleting tmp directory %s\n " % self .tmpdir )
333
-
334
- def __del__ (self ):
335
- _log .debug ("deleting LatexManager" )
336
- self ._cleanup ()
337
-
338
317
def get_width_height_descent (self , text , prop ):
339
318
"""
340
319
Get the width, total height and descent for a text typeset by the
@@ -766,16 +745,25 @@ class GraphicsContextPgf(GraphicsContextBase):
766
745
pass
767
746
768
747
748
+ @cbook .deprecated ("3.4" )
769
749
class TmpDirCleaner :
770
- remaining_tmpdirs = set ()
750
+ _remaining_tmpdirs = set ()
751
+
752
+ @cbook ._classproperty
753
+ @cbook .deprecated ("3.4" )
754
+ def remaining_tmpdirs (cls ):
755
+ return cls ._remaining_tmpdirs
771
756
772
757
@staticmethod
758
+ @cbook .deprecated ("3.4" )
773
759
def add (tmpdir ):
774
- TmpDirCleaner .remaining_tmpdirs .add (tmpdir )
760
+ TmpDirCleaner ._remaining_tmpdirs .add (tmpdir )
775
761
776
762
@staticmethod
763
+ @cbook .deprecated ("3.4" )
764
+ @atexit .register
777
765
def cleanup_remaining_tmpdirs ():
778
- for tmpdir in TmpDirCleaner .remaining_tmpdirs :
766
+ for tmpdir in TmpDirCleaner ._remaining_tmpdirs :
779
767
error_message = "error deleting tmp directory {}" .format (tmpdir )
780
768
shutil .rmtree (
781
769
tmpdir ,
@@ -930,14 +918,6 @@ class _BackendPgf(_Backend):
930
918
FigureCanvas = FigureCanvasPgf
931
919
932
920
933
- def _cleanup_all ():
934
- LatexManager ._cleanup_remaining_instances ()
935
- TmpDirCleaner .cleanup_remaining_tmpdirs ()
936
-
937
-
938
- atexit .register (_cleanup_all )
939
-
940
-
941
921
class PdfPages :
942
922
"""
943
923
A multi-page PDF file using the pgf backend
0 commit comments