Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@

.. towncrier release notes start

********************
*********************
4.11.8 (2026-09-08)
********************
*********************

- Make :func:`~platformdirs.user_data_path`, :func:`~platformdirs.user_config_path`,
:func:`~platformdirs.user_preference_path` and :func:`~platformdirs.user_applications_path` return the first site entry
when root is redirected by ``use_site_for_root`` under ``multipath``, matching their ``site_*_path`` twins. They passed
the whole joined list to :class:`~pathlib.Path`, giving one unusable path such as ``/xdg/a/foo:/xdg/b/foo`` - by
:user:`darrenhuai`. :pr:`538`
:func:`~platformdirs.user_preference_path` and :func:`~platformdirs.user_applications_path` return the first site
entry when root is redirected by ``use_site_for_root`` under ``multipath``, matching their ``site_*_path`` twins. They
passed the whole joined list to :class:`~pathlib.Path`, giving one unusable path such as ``/xdg/a/foo:/xdg/b/foo`` -
by :user:`darrenhuai`. :pr:`538`
- Ignore relative paths in XDG Base Directory environment variables and use the existing platform fallback. Relative
entries in ``$XDG_DATA_DIRS`` and ``$XDG_CONFIG_DIRS`` are skipped. :pr:`540`
- Preserve literal percent signs in Unix ``user-dirs.dirs`` paths, including ``100% complete``, ``100%%`` and
``%(XDG_DESKTOP_DIR)s``. Continue to expand ``$HOME``. :pr:`542`
- Use the base Python installation to locate Homebrew site directories on macOS, preserving shared data, config, cache and
state paths inside virtual environments. :pr:`543`
- Use the base Python installation to locate Homebrew site directories on macOS, preserving shared data, config, cache
and state paths inside virtual environments. :pr:`543`

*********************
4.11.7 (2026-09-01)
Expand Down
1 change: 1 addition & 0 deletions docs/changelog/546.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Resolve ``user_publicshare_dir`` from ``PUBLIC`` on Windows when the user's home directory is unavailable.
5 changes: 4 additions & 1 deletion src/platformdirs/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ def user_projects_dir(self) -> str:
@property
def user_publicshare_dir(self) -> str:
r"""Public share directory e.g. ``C:\Users\Public``."""
return os.path.normpath(os.environ.get("PUBLIC", str(Path("~").expanduser().parent / "Public")))
path = os.environ.get("PUBLIC")
if path is None:
path = str(Path("~").expanduser().parent / "Public")
return os.path.normpath(path)

@property
def user_templates_dir(self) -> str:
Expand Down
12 changes: 12 additions & 0 deletions tests/test_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ def test_windows(params: dict[str, Any], func: str) -> None:
assert result == expected_map[func]


def test_publicshare_dir_with_unavailable_home(monkeypatch: pytest.MonkeyPatch, mocker: MockerFixture) -> None:
monkeypatch.setenv("PUBLIC", r"C:\Users\Shared")
mocker.patch.object(Path, "expanduser", side_effect=RuntimeError("Could not determine home directory."))
assert Windows().user_publicshare_dir == os.path.normpath(r"C:\Users\Shared")


def test_publicshare_dir_fallback(monkeypatch: pytest.MonkeyPatch, mocker: MockerFixture) -> None:
monkeypatch.delenv("PUBLIC", raising=False)
mocker.patch.object(Path, "expanduser", return_value=Path("C:/Users/Test"))
assert Windows().user_publicshare_dir == os.path.normpath("C:/Users/Public")


def test_roaming_uses_appdata(mocker: MockerFixture) -> None:
mock = mocker.patch("platformdirs.windows.get_win_folder", side_effect=lambda csidl: _WIN_FOLDERS[csidl])
_result = Windows(appname="foo", roaming=True).user_data_dir
Expand Down