diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 48ab83f168c0..02c406dbb32b 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -424,12 +424,14 @@ def _get_xdg_cache_dir(): return os.environ.get('XDG_CACHE_HOME') or str(Path.home() / ".cache") -def _get_config_or_cache_dir(xdg_base): +def _get_config_or_cache_dir(xdg_base_getter): configdir = os.environ.get('MPLCONFIGDIR') if configdir: configdir = Path(configdir).resolve() - elif sys.platform.startswith(('linux', 'freebsd')) and xdg_base: - configdir = Path(xdg_base, "matplotlib") + elif sys.platform.startswith(('linux', 'freebsd')): + # Only call _xdg_base_getter here so that MPLCONFIGDIR is tried first, + # as _xdg_base_getter can throw. + configdir = Path(xdg_base_getter(), "matplotlib") else: configdir = Path.home() / ".matplotlib" try: @@ -470,7 +472,7 @@ def get_configdir(): 4. Else, create a temporary directory, and use it as the configuration directory. """ - return _get_config_or_cache_dir(_get_xdg_config_dir()) + return _get_config_or_cache_dir(_get_xdg_config_dir) @_logged_cached('CACHEDIR=%s') @@ -481,7 +483,7 @@ def get_cachedir(): The procedure used to find the directory is the same as for _get_config_dir, except using ``$XDG_CACHE_HOME``/``$HOME/.cache`` instead. """ - return _get_config_or_cache_dir(_get_xdg_cache_dir()) + return _get_config_or_cache_dir(_get_xdg_cache_dir) @_logged_cached('matplotlib data path: %s') diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index a5fdc32b268b..a1ed4aac7865 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -129,14 +129,18 @@ # OS Font paths +try: + _HOME = Path.home() +except Exception: # Exceptions thrown by home() are not specified... + _HOME = Path(os.devnull) # Just an arbitrary path with no children. MSFolders = \ r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' MSFontDirectories = [ r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts'] MSUserFontDirectories = [ - str(Path.home() / 'AppData/Local/Microsoft/Windows/Fonts'), - str(Path.home() / 'AppData/Roaming/Microsoft/Windows/Fonts'), + str(_HOME / 'AppData/Local/Microsoft/Windows/Fonts'), + str(_HOME / 'AppData/Roaming/Microsoft/Windows/Fonts'), ] X11FontDirectories = [ # an old standard installation point @@ -149,9 +153,9 @@ # common application, not really useful "/usr/lib/openoffice/share/fonts/truetype/", # user fonts - str((Path(os.environ.get('XDG_DATA_HOME') or Path.home() / ".local/share")) + str((Path(os.environ.get('XDG_DATA_HOME') or _HOME / ".local/share")) / "fonts"), - str(Path.home() / ".fonts"), + str(_HOME / ".fonts"), ] OSXFontDirectories = [ "/Library/Fonts/", @@ -160,7 +164,7 @@ # fonts installed via MacPorts "/opt/local/share/fonts", # user fonts - str(Path.home() / "Library/Fonts"), + str(_HOME / "Library/Fonts"), ] diff --git a/lib/matplotlib/tests/test_matplotlib.py b/lib/matplotlib/tests/test_matplotlib.py index c55b411ec31b..cad9433a562e 100644 --- a/lib/matplotlib/tests/test_matplotlib.py +++ b/lib/matplotlib/tests/test_matplotlib.py @@ -25,6 +25,14 @@ def test_tmpconfigdir_warning(tmpdir): os.chmod(tmpdir, mode) +def test_importable_with_no_home(tmpdir): + subprocess.run( + [sys.executable, "-c", + "import pathlib; pathlib.Path.home = lambda *args: 1/0; " + "import matplotlib.pyplot"], + env={**os.environ, "MPLCONFIGDIR": str(tmpdir)}, check=True) + + def test_use_doc_standard_backends(): """ Test that the standard backends mentioned in the docstring of