Skip to content

Commit 63f2914

Browse 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 97ba9d4 commit 63f2914

File tree

3 files changed

+59
-42
lines changed

3 files changed

+59
-42
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
``dviread.find_tex_file`` raises ``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.

lib/matplotlib/dviread.py

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,6 @@ 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)
477475

@@ -992,21 +990,20 @@ def search(self, filename):
992990
self._proc.stdin.write(os.fsencode(filename) + b"\n")
993991
self._proc.stdin.flush()
994992
out = self._proc.stdout.readline().rstrip()
995-
return "" if out == b"nil" else os.fsdecode(out)
993+
return None if out == b"nil" else os.fsdecode(out)
996994

997995

998996
@lru_cache()
999997
@_api.delete_parameter("3.5", "format")
1000998
def find_tex_file(filename, format=None):
1001999
"""
1002-
Find a file in the texmf tree.
1000+
Find a file in the texmf tree using kpathsea_.
10031001
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.
1002+
The kpathsea library, provided by most existing TeX distributions, both
1003+
on Unix-like systems and on Windows (MikTeX), is invoked via a long-lived
1004+
luatex process if luatex is installed, or via kpsewhich otherwise.
10081005
1009-
*If the file is not found, an empty string is returned*.
1006+
.. _kpathsea: http://www.tug.org/kpathsea/
10101007
10111008
Parameters
10121009
----------
@@ -1016,10 +1013,10 @@ def find_tex_file(filename, format=None):
10161013
Could be e.g. 'tfm' or 'vf' to limit the search to that type of files.
10171014
Deprecated.
10181015
1019-
References
1020-
----------
1021-
.. [1] `Kpathsea documentation <http://www.tug.org/kpathsea/>`_
1022-
The library that :program:`kpsewhich` is part of.
1016+
Raises
1017+
------
1018+
FileNotFoundError
1019+
If the file is not found.
10231020
"""
10241021

10251022
# we expect these to always be ascii encoded, but use utf-8
@@ -1029,39 +1026,51 @@ def find_tex_file(filename, format=None):
10291026
if isinstance(format, bytes):
10301027
format = format.decode('utf-8', errors='replace')
10311028

1032-
if format is None:
1033-
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]
10541029
try:
1055-
result = cbook._check_and_log_subprocess(cmd, _log, **kwargs)
1056-
except (FileNotFoundError, RuntimeError):
1057-
return ''
1058-
return result.rstrip('\n')
1030+
lk = _LuatexKpsewhich()
1031+
except FileNotFoundError:
1032+
lk = None # Fallback to directly calling kpsewhich, as below.
1033+
1034+
if lk and format is None:
1035+
path = lk.search(filename)
1036+
1037+
else:
1038+
if os.name == 'nt':
1039+
# On Windows only, kpathsea can use utf-8 for cmd args and output.
1040+
# The `command_line_encoding` environment variable is set to force
1041+
# it to always use utf-8 encoding. See Matplotlib issue #11848.
1042+
kwargs = {'env': {**os.environ, 'command_line_encoding': 'utf-8'},
1043+
'encoding': 'utf-8'}
1044+
else: # On POSIX, run through the equivalent of os.fsdecode().
1045+
kwargs = {'encoding': sys.getfilesystemencoding(),
1046+
'errors': 'surrogatescape'}
1047+
1048+
cmd = ['kpsewhich']
1049+
if format is not None:
1050+
cmd += ['--format=' + format]
1051+
cmd += [filename]
1052+
try:
1053+
path = (cbook._check_and_log_subprocess(cmd, _log, **kwargs)
1054+
.rstrip('\n'))
1055+
except (FileNotFoundError, RuntimeError):
1056+
path = None
1057+
1058+
if path:
1059+
return path
1060+
else:
1061+
raise FileNotFoundError(
1062+
f"Matplotlib's TeX implementation searched for a file named "
1063+
f"{filename!r} in your texmf tree, but could not find it")
10591064

10601065

10611066
@lru_cache()
10621067
def _fontfile(cls, suffix, texname):
1063-
filename = find_tex_file(texname + suffix)
1064-
return cls(filename) if filename else None
1068+
try:
1069+
filename = find_tex_file(texname + suffix)
1070+
except FileNotFoundError:
1071+
return None
1072+
else:
1073+
return cls(filename)
10651074

10661075

10671076
_tfmfile = partial(_fontfile, Tfm, ".tfm")

lib/matplotlib/testing/__init__.py

Lines 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

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