Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1c3e043

Browse files
authored
Merge pull request #30431 from anntzer/tp
Use pathlib in texmanager.
2 parents be68dfe + 8f2e158 commit 1c3e043

File tree

1 file changed

+34
-30
lines changed

1 file changed

+34
-30
lines changed

lib/matplotlib/texmanager.py

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import functools
2424
import hashlib
2525
import logging
26-
import os
2726
from pathlib import Path
2827
import subprocess
2928
from tempfile import TemporaryDirectory
@@ -63,7 +62,7 @@ class TexManager:
6362
Repeated calls to this constructor always return the same instance.
6463
"""
6564

66-
_texcache = os.path.join(mpl.get_cachedir(), 'tex.cache')
65+
_cache_dir = Path(mpl.get_cachedir(), 'tex.cache')
6766
_grey_arrayd = {}
6867

6968
_font_families = ('serif', 'sans-serif', 'cursive', 'monospace')
@@ -109,7 +108,7 @@ class TexManager:
109108

110109
@functools.lru_cache # Always return the same instance.
111110
def __new__(cls):
112-
Path(cls._texcache).mkdir(parents=True, exist_ok=True)
111+
cls._cache_dir.mkdir(parents=True, exist_ok=True)
113112
return object.__new__(cls)
114113

115114
@classmethod
@@ -167,23 +166,30 @@ def _get_font_preamble_and_command(cls):
167166
return preamble, fontcmd
168167

169168
@classmethod
170-
def get_basefile(cls, tex, fontsize, dpi=None):
169+
def _get_base_path(cls, tex, fontsize, dpi=None):
171170
"""
172-
Return a filename based on a hash of the string, fontsize, and dpi.
171+
Return a file path based on a hash of the string, fontsize, and dpi.
173172
"""
174173
src = cls._get_tex_source(tex, fontsize) + str(dpi)
175174
filehash = hashlib.sha256(
176175
src.encode('utf-8'),
177176
usedforsecurity=False
178177
).hexdigest()
179-
filepath = Path(cls._texcache)
178+
filepath = cls._cache_dir
180179

181180
num_letters, num_levels = 2, 2
182181
for i in range(0, num_letters*num_levels, num_letters):
183-
filepath = filepath / Path(filehash[i:i+2])
182+
filepath = filepath / filehash[i:i+2]
184183

185184
filepath.mkdir(parents=True, exist_ok=True)
186-
return os.path.join(filepath, filehash)
185+
return filepath / filehash
186+
187+
@classmethod
188+
def get_basefile(cls, tex, fontsize, dpi=None): # Kept for backcompat.
189+
"""
190+
Return a filename based on a hash of the string, fontsize, and dpi.
191+
"""
192+
return str(cls._get_base_path(tex, fontsize, dpi))
187193

188194
@classmethod
189195
def get_font_preamble(cls):
@@ -241,17 +247,16 @@ def make_tex(cls, tex, fontsize):
241247
242248
Return the file name.
243249
"""
244-
texfile = cls.get_basefile(tex, fontsize) + ".tex"
245-
Path(texfile).write_text(cls._get_tex_source(tex, fontsize),
246-
encoding='utf-8')
247-
return texfile
250+
texpath = cls._get_base_path(tex, fontsize).with_suffix(".tex")
251+
texpath.write_text(cls._get_tex_source(tex, fontsize), encoding='utf-8')
252+
return str(texpath)
248253

249254
@classmethod
250255
def _run_checked_subprocess(cls, command, tex, *, cwd=None):
251256
_log.debug(cbook._pformat_subprocess(command))
252257
try:
253258
report = subprocess.check_output(
254-
command, cwd=cwd if cwd is not None else cls._texcache,
259+
command, cwd=cwd if cwd is not None else cls._cache_dir,
255260
stderr=subprocess.STDOUT)
256261
except FileNotFoundError as exc:
257262
raise RuntimeError(
@@ -279,8 +284,8 @@ def make_dvi(cls, tex, fontsize):
279284
280285
Return the file name.
281286
"""
282-
dvifile = Path(cls.get_basefile(tex, fontsize)).with_suffix(".dvi")
283-
if not dvifile.exists():
287+
dvipath = cls._get_base_path(tex, fontsize).with_suffix(".dvi")
288+
if not dvipath.exists():
284289
# Generate the tex and dvi in a temporary directory to avoid race
285290
# conditions e.g. if multiple processes try to process the same tex
286291
# string at the same time. Having tmpdir be a subdirectory of the
@@ -290,17 +295,17 @@ def make_dvi(cls, tex, fontsize):
290295
# the absolute path may contain characters (e.g. ~) that TeX does
291296
# not support; n.b. relative paths cannot traverse parents, or it
292297
# will be blocked when `openin_any = p` in texmf.cnf).
293-
with TemporaryDirectory(dir=dvifile.parent) as tmpdir:
298+
with TemporaryDirectory(dir=dvipath.parent) as tmpdir:
294299
Path(tmpdir, "file.tex").write_text(
295300
cls._get_tex_source(tex, fontsize), encoding='utf-8')
296301
cls._run_checked_subprocess(
297302
["latex", "-interaction=nonstopmode", "--halt-on-error",
298303
"file.tex"], tex, cwd=tmpdir)
299-
Path(tmpdir, "file.dvi").replace(dvifile)
304+
Path(tmpdir, "file.dvi").replace(dvipath)
300305
# Also move the tex source to the main cache directory, but
301306
# only for backcompat.
302-
Path(tmpdir, "file.tex").replace(dvifile.with_suffix(".tex"))
303-
return str(dvifile)
307+
Path(tmpdir, "file.tex").replace(dvipath.with_suffix(".tex"))
308+
return str(dvipath)
304309

305310
@classmethod
306311
def make_png(cls, tex, fontsize, dpi):
@@ -309,13 +314,12 @@ def make_png(cls, tex, fontsize, dpi):
309314
310315
Return the file name.
311316
"""
312-
pngfile = Path(cls.get_basefile(tex, fontsize)).with_suffix(".png")
313-
# see get_rgba for a discussion of the background
314-
if not pngfile.exists():
315-
dvifile = cls.make_dvi(tex, fontsize)
316-
with TemporaryDirectory(dir=pngfile.parent) as tmpdir:
317+
pngpath = cls._get_base_path(tex, fontsize, dpi).with_suffix(".png")
318+
if not pngpath.exists():
319+
dvipath = cls.make_dvi(tex, fontsize)
320+
with TemporaryDirectory(dir=pngpath.parent) as tmpdir:
317321
cmd = ["dvipng", "-bg", "Transparent", "-D", str(dpi),
318-
"-T", "tight", "-o", "file.png", dvifile]
322+
"-T", "tight", "-o", "file.png", dvipath]
319323
# When testing, disable FreeType rendering for reproducibility;
320324
# but dvipng 1.16 has a bug (fixed in f3ff241) that breaks
321325
# --freetype0 mode, so for it we keep FreeType enabled; the
@@ -324,8 +328,8 @@ def make_png(cls, tex, fontsize, dpi):
324328
mpl._get_executable_info("dvipng").raw_version != "1.16"):
325329
cmd.insert(1, "--freetype0")
326330
cls._run_checked_subprocess(cmd, tex, cwd=tmpdir)
327-
Path(tmpdir, "file.png").replace(pngfile)
328-
return str(pngfile)
331+
Path(tmpdir, "file.png").replace(pngpath)
332+
return str(pngpath)
329333

330334
@classmethod
331335
def get_grey(cls, tex, fontsize=None, dpi=None):
@@ -336,7 +340,7 @@ def get_grey(cls, tex, fontsize=None, dpi=None):
336340
alpha = cls._grey_arrayd.get(key)
337341
if alpha is None:
338342
pngfile = cls.make_png(tex, fontsize, dpi)
339-
rgba = mpl.image.imread(os.path.join(cls._texcache, pngfile))
343+
rgba = mpl.image.imread(pngfile)
340344
cls._grey_arrayd[key] = alpha = rgba[:, :, -1]
341345
return alpha
342346

@@ -362,9 +366,9 @@ def get_text_width_height_descent(cls, tex, fontsize, renderer=None):
362366
"""Return width, height and descent of the text."""
363367
if tex.strip() == '':
364368
return 0, 0, 0
365-
dvifile = cls.make_dvi(tex, fontsize)
369+
dvipath = cls.make_dvi(tex, fontsize)
366370
dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
367-
with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:
371+
with dviread.Dvi(dvipath, 72 * dpi_fraction) as dvi:
368372
page, = dvi
369373
# A total height (including the descent) needs to be returned.
370374
return page.width, page.height + page.descent, page.descent

0 commit comments

Comments
 (0)