matplotlib/matplotlib · warning · ExecutableNotFoundError
str(_ose)
Error message
str(_ose)
What it means
Same pybind11 constructor path as hinting_factor: supplying `_kerning_factor` to matplotlib.ft2font.FT2Font (src/ft2font_wrapper.cpp:420-426) warns; the value is accepted until removal in 3.13, after which it becomes a TypeError. It also fires indirectly: font_manager._get_font forwards rcParams['text.kerning_factor'] into every FT2Font it creates (font_manager.py:1772, 1688), so setting that rcParam to a non-None int makes each newly instantiated font warn (per-thread font caching means it warns once per font). The leading underscore already marks the kwarg as internal API.
Source
Thrown at lib/matplotlib/__init__.py:417
# Execute the subprocess specified by args; capture stdout and stderr.
# Search for a regex match in the output; if the match succeeds, the
# first group of the match is the version.
# Return an _ExecInfo if the executable exists, and has a version of
# at least min_ver (if set); else, raise ExecutableNotFoundError.
try:
output = subprocess.check_output(
args, stderr=subprocess.STDOUT,
text=True, errors="replace", timeout=30)
except subprocess.CalledProcessError as _cpe:
if ignore_exit_code:
output = _cpe.output
else:
raise ExecutableNotFoundError(str(_cpe)) from _cpe
except subprocess.TimeoutExpired as _te:
msg = f"Timed out running {cbook._pformat_subprocess(args)}"
raise ExecutableNotFoundError(msg) from _te
except OSError as _ose:
raise ExecutableNotFoundError(str(_ose)) from _ose
match = re.search(regex, output)
if match:
raw_version = match.group(1)
version = parse_version(raw_version)
if min_ver is not None and version < parse_version(min_ver):
raise ExecutableNotFoundError(
f"You have {args[0]} version {version} but the minimum "
f"version supported by Matplotlib is {min_ver}")
return _ExecInfo(args[0], raw_version, version)
else:
raise ExecutableNotFoundError(
f"Failed to determine the version of {args[0]} from "
f"{' '.join(args)}, which output {output}")
if name in os.environ.get("_MPLHIDEEXECUTABLES", "").split(","):
raise ExecutableNotFoundError(f"{name} was hidden")
if name == "dvipng":View on GitHub (pinned to b379c1b69e)
Solutions
- Stop passing `_kerning_factor`; it is underscore-private and its public handle, the `text.kerning_factor` rcParam, is itself deprecated.
- If you changed kerning globally, remove the rcParam assignment and rely on default kerning; if you must keep it temporarily, accept that each new font warns once due to caching.
- Suppress the specific noise: `warnings.filterwarnings('ignore', message='The _kerning_factor parameter was deprecated')`.
- Pin `matplotlib<3.11` only as a stopgap while migrating callers.
Example fix
# before from matplotlib import ft2font font = ft2font.FT2Font(path, _kerning_factor=2) # after from matplotlib import ft2font font = ft2font.FT2Font(path) # private kwarg dropped; use default kerning
Defensive patterns
Strategy: validation
Validate before calling
import matplotlib
from packaging.version import Version
from matplotlib import ft2font
kwargs = {}
if Version(matplotlib.__version__) < Version("3.11"):
kwargs["_kerning_factor"] = 2
font = ft2font.FT2Font(path, **kwargs) # kwarg warns in 3.11, TypeError in 3.13 Try / catch
import warnings
import matplotlib as mpl
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always", mpl.MatplotlibDeprecationWarning)
font = ft2font.FT2Font(path, _kerning_factor=2) # last use while migrating
assert not [w for w in caught if "_kerning_factor" in str(w.message)], "still passing the deprecated kwarg" Prevention
- Never call parameters with a leading underscore from user code; they are matplotlib-internal by convention.
- When upgrading to 3.11+, grep code and style files for _kerning_factor and text.kerning_factor.
- Run CI with MatplotlibDeprecationWarning as error to catch these before the 3.13 removal.
- Rely on matplotlib's per-thread font cache: construct fonts once so any residual warning fires at most once per font.
When it happens
Trigger: `ft2font.FT2Font(file, _kerning_factor=123)` (any int; a float like 1.3 raises TypeError first because the C++ signature takes int, per test_ft2font.py:231-238); or `mpl.rcParams['text.kerning_factor'] = 2` followed by any text rendering that instantiates a new font.
Common situations: Typographic code fine-tuning letter spacing for pixel-tight labels; tools built directly on FT2Font; upgrading to 3.11 with a style file or rcParams block that still sets text.kerning_factor, causing warnings during text layout.
Related errors
- Timed out running {cbook._pformat_subprocess(args)}
- You have {args[0]} version {version} but the minimum version
- 'Figure' object has no attribute 'number'. In the future thi
- Indexing TTC fonts is not supported yet
- Tick direction ({self._tick_dir!r}) not supported by get_tic
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/ebfb2f1370454fb8.
Report an issue: GitHub.