Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7785784

Browse filesBrowse files
committed
Raise an exception when find_tex_file fails to find a file.
The exception message is clearer for end users than downstream callers failing to `open()` a file named `""`. Also update the function's docstring. _tfmfile now never returns None (an exception would have been raised earlier by find_tex_file), so remove the corresponding branch.
1 parent 69931a6 commit 7785784
Copy full SHA for 7785784

File tree

Expand file treeCollapse file tree

6 files changed

+82
-51
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+82
-51
lines changed
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
In the future, ``dviread.find_tex_file`` will raise a ``FileNotFoundError`` for missing files
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Previously, it would return an empty string in such cases. Raising an
4+
exception allows attaching a user-friendly message instead. During the
5+
transition period, a warning is raised.

‎lib/matplotlib/backends/backend_pdf.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_pdf.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ def dviFontName(self, dvifont):
887887
if dvi_info is not None:
888888
return dvi_info.pdfname
889889

890-
tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map'))
890+
tex_font_map = dviread.PsfontsMap(dviread._find_tex_file('pdftex.map'))
891891
psfont = tex_font_map[dvifont.texname]
892892
if psfont.filename is None:
893893
raise ValueError(

‎lib/matplotlib/dviread.py

Copy file name to clipboardExpand all lines: lib/matplotlib/dviread.py
+69-47Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -470,13 +470,12 @@ def _fnt_def_real(self, k, c, s, d, a, l):
470470
n = self.file.read(a + l)
471471
fontname = n[-l:].decode('ascii')
472472
tfm = _tfmfile(fontname)
473-
if tfm is None:
474-
raise FileNotFoundError("missing font metrics file: %s" % fontname)
475473
if c != 0 and tfm.checksum != 0 and c != tfm.checksum:
476474
raise ValueError('tfm checksum mismatch: %s' % n)
477-
478-
vf = _vffile(fontname)
479-
475+
try:
476+
vf = _vffile(fontname)
477+
except FileNotFoundError:
478+
vf = None
480479
self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf)
481480

482481
@_dispatch(247, state=_dvistate.pre, args=('u1', 'u4', 'u4', 'u4', 'u1'))
@@ -938,9 +937,9 @@ def _parse_and_cache_line(self, line):
938937
if basename is None:
939938
basename = tfmname
940939
if encodingfile is not None:
941-
encodingfile = find_tex_file(encodingfile)
940+
encodingfile = _find_tex_file(encodingfile)
942941
if fontfile is not None:
943-
fontfile = find_tex_file(fontfile)
942+
fontfile = _find_tex_file(fontfile)
944943
self._parsed[tfmname] = PsFont(
945944
texname=tfmname, psname=basename, effects=effects,
946945
encoding=encodingfile, filename=fontfile)
@@ -992,21 +991,20 @@ def search(self, filename):
992991
self._proc.stdin.write(os.fsencode(filename) + b"\n")
993992
self._proc.stdin.flush()
994993
out = self._proc.stdout.readline().rstrip()
995-
return "" if out == b"nil" else os.fsdecode(out)
994+
return None if out == b"nil" else os.fsdecode(out)
996995

997996

998997
@lru_cache()
999998
@_api.delete_parameter("3.5", "format")
1000-
def find_tex_file(filename, format=None):
999+
def _find_tex_file(filename, format=None):
10011000
"""
1002-
Find a file in the texmf tree.
1001+
Find a file in the texmf tree using kpathsea_.
10031002
1004-
Calls :program:`kpsewhich` which is an interface to the kpathsea
1005-
library [1]_. Most existing TeX distributions on Unix-like systems use
1006-
kpathsea. It is also available as part of MikTeX, a popular
1007-
distribution on Windows.
1003+
The kpathsea library, provided by most existing TeX distributions, both
1004+
on Unix-like systems and on Windows (MikTeX), is invoked via a long-lived
1005+
luatex process if luatex is installed, or via kpsewhich otherwise.
10081006
1009-
*If the file is not found, an empty string is returned*.
1007+
.. _kpathsea: https://www.tug.org/kpathsea/
10101008
10111009
Parameters
10121010
----------
@@ -1016,10 +1014,10 @@ def find_tex_file(filename, format=None):
10161014
Could be e.g. 'tfm' or 'vf' to limit the search to that type of files.
10171015
Deprecated.
10181016
1019-
References
1020-
----------
1021-
.. [1] `Kpathsea documentation <http://www.tug.org/kpathsea/>`_
1022-
The library that :program:`kpsewhich` is part of.
1017+
Raises
1018+
------
1019+
FileNotFoundError
1020+
If the file is not found.
10231021
"""
10241022

10251023
# we expect these to always be ascii encoded, but use utf-8
@@ -1029,39 +1027,63 @@ def find_tex_file(filename, format=None):
10291027
if isinstance(format, bytes):
10301028
format = format.decode('utf-8', errors='replace')
10311029

1032-
if format is None:
1030+
try:
1031+
lk = _LuatexKpsewhich()
1032+
except FileNotFoundError:
1033+
lk = None # Fallback to directly calling kpsewhich, as below.
1034+
1035+
if lk and format is None:
1036+
path = lk.search(filename)
1037+
1038+
else:
1039+
if os.name == 'nt':
1040+
# On Windows only, kpathsea can use utf-8 for cmd args and output.
1041+
# The `command_line_encoding` environment variable is set to force
1042+
# it to always use utf-8 encoding. See Matplotlib issue #11848.
1043+
kwargs = {'env': {**os.environ, 'command_line_encoding': 'utf-8'},
1044+
'encoding': 'utf-8'}
1045+
else: # On POSIX, run through the equivalent of os.fsdecode().
1046+
kwargs = {'encoding': sys.getfilesystemencoding(),
1047+
'errors': 'surrogateescape'}
1048+
1049+
cmd = ['kpsewhich']
1050+
if format is not None:
1051+
cmd += ['--format=' + format]
1052+
cmd += [filename]
10331053
try:
1034-
lk = _LuatexKpsewhich()
1035-
except FileNotFoundError:
1036-
pass # Fallback to directly calling kpsewhich, as below.
1037-
else:
1038-
return lk.search(filename)
1039-
1040-
if os.name == 'nt':
1041-
# On Windows only, kpathsea can use utf-8 for cmd args and output.
1042-
# The `command_line_encoding` environment variable is set to force it
1043-
# to always use utf-8 encoding. See Matplotlib issue #11848.
1044-
kwargs = {'env': {**os.environ, 'command_line_encoding': 'utf-8'},
1045-
'encoding': 'utf-8'}
1046-
else: # On POSIX, run through the equivalent of os.fsdecode().
1047-
kwargs = {'encoding': sys.getfilesystemencoding(),
1048-
'errors': 'surrogatescape'}
1049-
1050-
cmd = ['kpsewhich']
1051-
if format is not None:
1052-
cmd += ['--format=' + format]
1053-
cmd += [filename]
1054+
path = (cbook._check_and_log_subprocess(cmd, _log, **kwargs)
1055+
.rstrip('\n'))
1056+
except (FileNotFoundError, RuntimeError):
1057+
path = None
1058+
1059+
if path:
1060+
return path
1061+
else:
1062+
raise FileNotFoundError(
1063+
f"Matplotlib's TeX implementation searched for a file named "
1064+
f"{filename!r} in your texmf tree, but could not find it")
1065+
1066+
1067+
# After the deprecation period elapses, delete this shim and rename
1068+
# _find_tex_file to find_tex_file everywhere.
1069+
@_api.delete_parameter("3.5", "format")
1070+
def find_tex_file(filename, format=None):
10541071
try:
1055-
result = cbook._check_and_log_subprocess(cmd, _log, **kwargs)
1056-
except (FileNotFoundError, RuntimeError):
1057-
return ''
1058-
return result.rstrip('\n')
1072+
return (_find_tex_file(filename, format) if format is not None else
1073+
_find_tex_file(filename))
1074+
except FileNotFoundError as exc:
1075+
_api.warn_deprecated(
1076+
"3.6", message=f"{exc.args[0]}; in the future, this will raise a "
1077+
f"FileNotFoundError.")
1078+
return ""
1079+
1080+
1081+
find_tex_file.__doc__ = _find_tex_file.__doc__
10591082

10601083

10611084
@lru_cache()
10621085
def _fontfile(cls, suffix, texname):
1063-
filename = find_tex_file(texname + suffix)
1064-
return cls(filename) if filename else None
1086+
return cls(_find_tex_file(texname + suffix))
10651087

10661088

10671089
_tfmfile = partial(_fontfile, Tfm, ".tfm")
@@ -1077,7 +1099,7 @@ def _fontfile(cls, suffix, texname):
10771099
parser.add_argument("dpi", nargs="?", type=float, default=None)
10781100
args = parser.parse_args()
10791101
with Dvi(args.filename, args.dpi) as dvi:
1080-
fontmap = PsfontsMap(find_tex_file('pdftex.map'))
1102+
fontmap = PsfontsMap(_find_tex_file('pdftex.map'))
10811103
for page in dvi:
10821104
print(f"=== new page === "
10831105
f"(w: {page.width}, h: {page.height}, d: {page.descent})")

‎lib/matplotlib/testing/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/testing/__init__.py
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,8 @@ def _check_for_pgf(texsystem):
7878

7979

8080
def _has_tex_package(package):
81-
return bool(mpl.dviread.find_tex_file(f"{package}.sty"))
81+
try:
82+
mpl.dviread._find_tex_file(f"{package}.sty")
83+
return True
84+
except FileNotFoundError:
85+
return False

‎lib/matplotlib/tests/test_dviread.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_dviread.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88

99
def test_PsfontsMap(monkeypatch):
10-
monkeypatch.setattr(dr, 'find_tex_file', lambda x: x)
10+
monkeypatch.setattr(dr, '_find_tex_file', lambda x: x)
1111

1212
filename = str(Path(__file__).parent / 'baseline_images/dviread/test.map')
1313
fontmap = dr.PsfontsMap(filename)

‎lib/matplotlib/textpath.py

Copy file name to clipboardExpand all lines: lib/matplotlib/textpath.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
279279
@staticmethod
280280
@functools.lru_cache(50)
281281
def _get_ps_font_and_encoding(texname):
282-
tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map'))
282+
tex_font_map = dviread.PsfontsMap(dviread._find_tex_file('pdftex.map'))
283283
psfont = tex_font_map[texname]
284284
if psfont.filename is None:
285285
raise ValueError(

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.