Problem
In reproducible or immutable environments — Nix store paths, read-only container layers, shared HPC installs — a natural pattern is to prewarm the font cache at build time and point MPLCONFIGDIR at the read-only result.
Today _get_config_or_cache_dir() gates on os.access(dir, os.W_OK) before anything else, so a directory containing a perfectly valid fontlist-*.json is rejected outright: matplotlib warns "... is not a writable directory", creates a temporary directory and rebuilds the font cache there on every process start — exactly the slow path the prewarmed cache was meant to avoid. On a small server (1 vCPU) that rebuild dominates our chart generation.
$ MPLCONFIGDIR=/tmp/warm python -c 'import matplotlib.font_manager' # prewarm
$ chmod -R a-w /tmp/warm
$ MPLCONFIGDIR=/tmp/warm python -c 'import matplotlib.pyplot'
Matplotlib created a temporary cache directory ... because there was an issue with the default path
Reproduced on 3.11.1; the W_OK gate is unchanged on current main.
Proposed solution
When MPLCONFIGDIR is set explicitly, exists and contains a loadable font cache for the current version, use it read-only, falling back to a temporary directory only for writes that are actually attempted. Alternatively, split cache-dir resolution from config-dir resolution so a read-only prewarmed cache can be honored explicitly.
Problem
In reproducible or immutable environments — Nix store paths, read-only container layers, shared HPC installs — a natural pattern is to prewarm the font cache at build time and point
MPLCONFIGDIRat the read-only result.Today
_get_config_or_cache_dir()gates onos.access(dir, os.W_OK)before anything else, so a directory containing a perfectly validfontlist-*.jsonis rejected outright: matplotlib warns"... is not a writable directory", creates a temporary directory and rebuilds the font cache there on every process start — exactly the slow path the prewarmed cache was meant to avoid. On a small server (1 vCPU) that rebuild dominates our chart generation.Reproduced on 3.11.1; the
W_OKgate is unchanged on currentmain.Proposed solution
When
MPLCONFIGDIRis set explicitly, exists and contains a loadable font cache for the current version, use it read-only, falling back to a temporary directory only for writes that are actually attempted. Alternatively, split cache-dir resolution from config-dir resolution so a read-only prewarmed cache can be honored explicitly.