Skip to content
Merged
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
2 changes: 2 additions & 0 deletions docs/changelog/537.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Give :func:`~platformdirs.user_bin_dir` and :func:`~platformdirs.user_bin_path` the ``use_site_for_root`` argument. They
took none, so neither could reach the Unix redirect of root to :func:`~platformdirs.site_bin_dir`.
20 changes: 14 additions & 6 deletions src/platformdirs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,13 @@ def user_preference_dir( # ruff:ignore[too-many-arguments]
).user_preference_dir


def user_bin_dir() -> str:
""":returns: bin directory tied to the user"""
return PlatformDirs().user_bin_dir
def user_bin_dir(*, use_site_for_root: bool = False) -> str:
""":param use_site_for_root: See `use_site_for_root <platformdirs.api.PlatformDirsABC.use_site_for_root>`.

:returns: bin directory tied to the user

"""
return PlatformDirs(use_site_for_root=use_site_for_root).user_bin_dir


def site_bin_dir() -> str:
Expand Down Expand Up @@ -849,9 +853,13 @@ def user_preference_path( # ruff:ignore[too-many-arguments]
).user_preference_path


def user_bin_path() -> Path:
""":returns: bin path tied to the user"""
return PlatformDirs().user_bin_path
def user_bin_path(*, use_site_for_root: bool = False) -> Path:
""":param use_site_for_root: See `use_site_for_root <platformdirs.api.PlatformDirsABC.use_site_for_root>`.

:returns: bin path tied to the user

"""
return PlatformDirs(use_site_for_root=use_site_for_root).user_bin_path


def site_bin_path() -> Path:
Expand Down
17 changes: 17 additions & 0 deletions tests/test_unix.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import importlib
import inspect
import os
import sys
import typing
Expand All @@ -9,6 +10,7 @@

import pytest

import platformdirs
from platformdirs import unix
from platformdirs.unix import Unix

Expand Down Expand Up @@ -464,6 +466,7 @@ def test_user_dirs_respects_xdg_config_home(tmp_path: Path, monkeypatch: pytest.
),
),
("user_bin_dir", "/usr/local/bin"),
("user_applications_dir", f"/usr/local/share{os.sep}applications"),
]


Expand All @@ -482,6 +485,20 @@ def test_use_site_for_root_as_non_root(prop: str, expected: str) -> None:
assert result != expected


@pytest.mark.usefixtures("_as_root", "_no_xdg_runtime_dir")
@pytest.mark.parametrize("suffix", ["dir", "path"])
@pytest.mark.parametrize(("prop", "expected"), _SITE_REDIRECT_CASES)
def test_use_site_for_root_reaches_the_module_function(
mocker: MockerFixture, prop: str, expected: str, suffix: str
) -> None:
# The module-level functions have to reach every property the site redirect touches.
mocker.patch("platformdirs.PlatformDirs", Unix)
function = getattr(platformdirs, prop.removesuffix("dir") + suffix)
accepted = inspect.Signature.from_callable(function).parameters
options = {"use_site_for_root": True, "appname": "foo"}
assert Path(function(**{k: v for k, v in options.items() if k in accepted})) == Path(expected)


@pytest.mark.usefixtures("_as_root", "_no_xdg_runtime_dir", "_writable_runtime_dir")
@pytest.mark.parametrize(("prop", "expected"), _SITE_REDIRECT_CASES)
def test_use_site_for_root_disabled_as_root(prop: str, expected: str) -> None:
Expand Down