diff --git a/CHANGES.rst b/CHANGES.rst index 761d251b..bdbc544b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,10 @@ platformdirs Changelog ====================== +platformdirs 2.2.0 +------------------ +- Unix: Fallback to default if XDG environment variable is empty + platformdirs 2.1.0 ------------------ - Add ``readthedocs.org`` documentation via Sphinx diff --git a/src/platformdirs/unix.py b/src/platformdirs/unix.py index 02beca29..3f6afec5 100644 --- a/src/platformdirs/unix.py +++ b/src/platformdirs/unix.py @@ -22,9 +22,8 @@ def user_data_dir(self) -> str: :return: data directory tied to the user, e.g. ``~/.local/share/$appname/$version`` or ``$XDG_DATA_HOME/$appname/$version`` """ - if "XDG_DATA_HOME" in os.environ: - path = os.environ["XDG_DATA_HOME"] - else: + path = os.environ.get("XDG_DATA_HOME", "") + if not path.strip(): path = os.path.expanduser("~/.local/share") return self._append_app_name_and_version(path) @@ -36,9 +35,8 @@ def site_data_dir(self) -> str: path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version`` """ # XDG default for $XDG_DATA_DIRS; only first, if multipath is False - if "XDG_DATA_DIRS" in os.environ: - path = os.environ["XDG_DATA_DIRS"] - else: + path = os.environ.get("XDG_DATA_DIRS", "") + if not path.strip(): path = f"/usr/local/share{os.pathsep}/usr/share" return self._with_multi_path(path) @@ -55,9 +53,8 @@ def user_config_dir(self) -> str: :return: config directory tied to the user, e.g. ``~/.config/$appname/$version`` or ``$XDG_CONFIG_HOME/$appname/$version`` """ - if "XDG_CONFIG_HOME" in os.environ: - path = os.environ["XDG_CONFIG_HOME"] - else: + path = os.environ.get("XDG_CONFIG_HOME", "") + if not path.strip(): path = os.path.expanduser("~/.config") return self._append_app_name_and_version(path) @@ -69,9 +66,8 @@ def site_config_dir(self) -> str: path separator), e.g. ``/etc/xdg/$appname/$version`` """ # XDG default for $XDG_CONFIG_DIRS only first, if multipath is False - if "XDG_CONFIG_DIRS" in os.environ: - path = os.environ["XDG_CONFIG_DIRS"] - else: + path = os.environ.get("XDG_CONFIG_DIRS", "") + if not path.strip(): path = "/etc/xdg" return self._with_multi_path(path) @@ -81,9 +77,8 @@ def user_cache_dir(self) -> str: :return: cache directory tied to the user, e.g. ``~/.cache/$appname/$version`` or ``~/$XDG_CACHE_HOME/$appname/$version`` """ - if "XDG_CACHE_HOME" in os.environ: - path = os.environ["XDG_CACHE_HOME"] - else: + path = os.environ.get("XDG_CACHE_HOME", "") + if not path.strip(): path = os.path.expanduser("~/.cache") return self._append_app_name_and_version(path) @@ -93,9 +88,8 @@ def user_state_dir(self) -> str: :return: state directory tied to the user, e.g. ``~/.local/state/$appname/$version`` or ``$XDG_STATE_HOME/$appname/$version`` """ - if "XDG_STATE_HOME" in os.environ: - path = os.environ["XDG_STATE_HOME"] - else: + path = os.environ.get("XDG_STATE_HOME", "") + if not path.strip(): path = os.path.expanduser("~/.local/state") return self._append_app_name_and_version(path) diff --git a/tests/test_unix.py b/tests/test_unix.py new file mode 100644 index 00000000..59e60e60 --- /dev/null +++ b/tests/test_unix.py @@ -0,0 +1,51 @@ +import os +import typing + +import pytest +from _pytest.monkeypatch import MonkeyPatch + +from platformdirs.unix import Unix + + +class XDGVariable(typing.NamedTuple): + name: str + default_value: str + + +def _func_to_path(func: str) -> XDGVariable: + mapping = { + "user_data_dir": XDGVariable("XDG_DATA_HOME", "~/.local/share"), + "site_data_dir": XDGVariable("XDG_DATA_DIRS", f"/usr/local/share{os.pathsep}/usr/share"), + "user_config_dir": XDGVariable("XDG_CONFIG_HOME", "~/.config"), + "site_config_dir": XDGVariable("XDG_CONFIG_DIRS", "/etc/xdg"), + "user_cache_dir": XDGVariable("XDG_CACHE_HOME", "~/.cache"), + "user_state_dir": XDGVariable("XDG_STATE_HOME", "~/.local/state"), + "user_log_dir": XDGVariable("XDG_CACHE_HOME", "~/.cache"), + } + return mapping[func] + + +@pytest.fixture() +def dirs_instance() -> Unix: + return Unix(multipath=True, opinion=False) + + +def test_xdg_variable_not_set(monkeypatch: MonkeyPatch, dirs_instance: Unix, func: str) -> None: + xdg_variable = _func_to_path(func) + monkeypatch.delenv(xdg_variable.name, raising=False) + result = getattr(dirs_instance, func) + assert result == os.path.expanduser(xdg_variable.default_value) + + +def test_xdg_variable_empty_value(monkeypatch: MonkeyPatch, dirs_instance: Unix, func: str) -> None: + xdg_variable = _func_to_path(func) + monkeypatch.setenv(xdg_variable.name, "") + result = getattr(dirs_instance, func) + assert result == os.path.expanduser(xdg_variable.default_value) + + +def test_xdg_variable_custom_value(monkeypatch: MonkeyPatch, dirs_instance: Unix, func: str) -> None: + xdg_variable = _func_to_path(func) + monkeypatch.setenv(xdg_variable.name, "/tmp/custom-dir") + result = getattr(dirs_instance, func) + assert result == "/tmp/custom-dir" diff --git a/whitelist.txt b/whitelist.txt index 7428da1c..c390319a 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -12,13 +12,11 @@ Dirs func highbit HKEY -impl intersphinx isfunction jnius kernel32 lru -macos multipath normpath ord @@ -28,7 +26,6 @@ pathlib pathsep platformdirs pyjnius -Runtime setenv shell32 typehints