platformdirs 4.13.2__tar.gz → 4.13.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {platformdirs-4.13.2 → platformdirs-4.13.4}/PKG-INFO +1 -1
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/android.py +2 -2
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/ios.py +17 -18
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/testing.py +4 -2
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/version.py +2 -2
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/windows.py +2 -1
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_android.py +26 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_ios.py +21 -1
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_testing.py +55 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_unix.py +1 -1
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_windows.py +8 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/.gitignore +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/LICENSE +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/README.md +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/pyproject.toml +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/__init__.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/__main__.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/_xdg.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/api.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/macos.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/py.typed +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/pytest_plugin.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/src/platformdirs/unix.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/conftest.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_api.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_comp_with_appdirs.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_macos.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_main.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tests/test_pytest_plugin.py +0 -0
- {platformdirs-4.13.2 → platformdirs-4.13.4}/tox.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: platformdirs
|
|
3
|
-
Version: 4.13.
|
|
3
|
+
Version: 4.13.4
|
|
4
4
|
Summary: A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
|
|
5
5
|
Project-URL: Changelog, https://platformdirs.readthedocs.io/en/latest/changelog.html
|
|
6
6
|
Project-URL: Documentation, https://platformdirs.readthedocs.io
|
|
@@ -189,7 +189,7 @@ def _android_folder() -> str | None:
|
|
|
189
189
|
/data/(?:data|user/\d+) # internal storage of the primary user or of user N
|
|
190
190
|
/[^/]+ # package name, one path segment
|
|
191
191
|
)
|
|
192
|
-
/files
|
|
192
|
+
/files(?=/|\Z) # the files directory the interpreter runs from
|
|
193
193
|
""",
|
|
194
194
|
re.VERBOSE,
|
|
195
195
|
)
|
|
@@ -209,7 +209,7 @@ def _android_folder() -> str | None:
|
|
|
209
209
|
/(?:data|user/\d+) # the primary user or user N
|
|
210
210
|
/[^/]+ # package name, one path segment
|
|
211
211
|
)
|
|
212
|
-
/files
|
|
212
|
+
/files(?=/|\Z) # the files directory the interpreter runs from
|
|
213
213
|
""",
|
|
214
214
|
re.VERBOSE,
|
|
215
215
|
)
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
|
|
5
|
+
from ._xdg import _expand_user
|
|
7
6
|
from .api import PlatformDirsABC
|
|
8
7
|
|
|
9
8
|
|
|
@@ -23,7 +22,7 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
23
22
|
@property
|
|
24
23
|
def user_data_dir(self) -> str:
|
|
25
24
|
"""Data directory tied to the user, e.g. ``~/Library/Application Support/$appname/$version``."""
|
|
26
|
-
return self._append_app_name_and_version(
|
|
25
|
+
return self._append_app_name_and_version(_expand_user("~/Library/Application Support"), private=True)
|
|
27
26
|
|
|
28
27
|
@property
|
|
29
28
|
def site_data_dir(self) -> str:
|
|
@@ -43,7 +42,7 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
43
42
|
@property
|
|
44
43
|
def user_cache_dir(self) -> str:
|
|
45
44
|
"""Cache directory tied to the user, e.g. ``~/Library/Caches/$appname/$version``."""
|
|
46
|
-
return self._append_app_name_and_version(
|
|
45
|
+
return self._append_app_name_and_version(_expand_user("~/Library/Caches"), private=True)
|
|
47
46
|
|
|
48
47
|
@property
|
|
49
48
|
def site_cache_dir(self) -> str:
|
|
@@ -63,7 +62,7 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
63
62
|
@property
|
|
64
63
|
def user_log_dir(self) -> str:
|
|
65
64
|
"""Log directory tied to the user, e.g. ``~/Library/Logs/$appname/$version``."""
|
|
66
|
-
return self._append_app_name_and_version(
|
|
65
|
+
return self._append_app_name_and_version(_expand_user("~/Library/Logs"), private=True)
|
|
67
66
|
|
|
68
67
|
@property
|
|
69
68
|
def site_log_dir(self) -> str:
|
|
@@ -73,53 +72,53 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
73
72
|
@property
|
|
74
73
|
def user_documents_dir(self) -> str:
|
|
75
74
|
"""Documents directory tied to the user, e.g. ``~/Documents``."""
|
|
76
|
-
return
|
|
75
|
+
return _expand_user("~/Documents")
|
|
77
76
|
|
|
78
77
|
# The app container has Documents but no other media folder, so the rest live inside it, as Qt places them.
|
|
79
78
|
@property
|
|
80
79
|
def user_downloads_dir(self) -> str:
|
|
81
80
|
"""Downloads directory tied to the user, e.g. ``~/Documents/Downloads``."""
|
|
82
|
-
return
|
|
81
|
+
return _expand_user("~/Documents/Downloads")
|
|
83
82
|
|
|
84
83
|
@property
|
|
85
84
|
def user_pictures_dir(self) -> str:
|
|
86
85
|
"""Pictures directory tied to the user, e.g. ``~/Documents/Pictures``."""
|
|
87
|
-
return
|
|
86
|
+
return _expand_user("~/Documents/Pictures")
|
|
88
87
|
|
|
89
88
|
@property
|
|
90
89
|
def user_videos_dir(self) -> str:
|
|
91
90
|
"""Videos directory tied to the user, e.g. ``~/Documents/Movies``."""
|
|
92
|
-
return
|
|
91
|
+
return _expand_user("~/Documents/Movies")
|
|
93
92
|
|
|
94
93
|
@property
|
|
95
94
|
def user_music_dir(self) -> str:
|
|
96
95
|
"""Music directory tied to the user, e.g. ``~/Documents/Music``."""
|
|
97
|
-
return
|
|
96
|
+
return _expand_user("~/Documents/Music")
|
|
98
97
|
|
|
99
98
|
@property
|
|
100
99
|
def user_desktop_dir(self) -> str:
|
|
101
100
|
"""Desktop directory tied to the user, e.g. ``~/Documents/Desktop``."""
|
|
102
|
-
return
|
|
101
|
+
return _expand_user("~/Documents/Desktop")
|
|
103
102
|
|
|
104
103
|
@property
|
|
105
104
|
def user_projects_dir(self) -> str:
|
|
106
105
|
"""Projects directory tied to the user, e.g. ``~/Documents/Projects``."""
|
|
107
|
-
return
|
|
106
|
+
return _expand_user("~/Documents/Projects")
|
|
108
107
|
|
|
109
108
|
@property
|
|
110
109
|
def user_publicshare_dir(self) -> str:
|
|
111
110
|
"""Public share directory tied to the user, e.g. ``~/Documents/Public``."""
|
|
112
|
-
return
|
|
111
|
+
return _expand_user("~/Documents/Public")
|
|
113
112
|
|
|
114
113
|
@property
|
|
115
114
|
def user_templates_dir(self) -> str:
|
|
116
115
|
"""Templates directory tied to the user, e.g. ``~/Documents/Templates``."""
|
|
117
|
-
return
|
|
116
|
+
return _expand_user("~/Documents/Templates")
|
|
118
117
|
|
|
119
118
|
@property
|
|
120
119
|
def user_fonts_dir(self) -> str:
|
|
121
120
|
"""Fonts directory tied to the user, e.g. ``~/Library/Fonts``."""
|
|
122
|
-
return
|
|
121
|
+
return _expand_user("~/Library/Fonts")
|
|
123
122
|
|
|
124
123
|
@property
|
|
125
124
|
def user_preference_dir(self) -> str:
|
|
@@ -130,7 +129,7 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
130
129
|
@property
|
|
131
130
|
def user_bin_dir(self) -> str:
|
|
132
131
|
"""Bin directory tied to the user, e.g. ``~/.local/bin``."""
|
|
133
|
-
return
|
|
132
|
+
return _expand_user("~/.local/bin")
|
|
134
133
|
|
|
135
134
|
@property
|
|
136
135
|
def site_bin_dir(self) -> str:
|
|
@@ -140,7 +139,7 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
140
139
|
@property
|
|
141
140
|
def user_applications_dir(self) -> str:
|
|
142
141
|
"""Applications directory tied to the user, e.g. ``~/Applications``."""
|
|
143
|
-
return
|
|
142
|
+
return _expand_user("~/Applications")
|
|
144
143
|
|
|
145
144
|
@property
|
|
146
145
|
def site_applications_dir(self) -> str:
|
|
@@ -150,7 +149,7 @@ class IOS(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
150
149
|
@property
|
|
151
150
|
def user_runtime_dir(self) -> str:
|
|
152
151
|
"""Runtime directory tied to the user, e.g. ``~/tmp/$appname/$version``."""
|
|
153
|
-
return self._append_app_name_and_version(
|
|
152
|
+
return self._append_app_name_and_version(_expand_user("~/tmp"), private=True)
|
|
154
153
|
|
|
155
154
|
@property
|
|
156
155
|
def site_runtime_dir(self) -> str:
|
|
@@ -39,6 +39,8 @@ def isolated_dirs(root: str | os.PathLike[str]) -> Generator[Path, None, None]:
|
|
|
39
39
|
``PlatformDirs("app", version="1.0").user_config_path`` becomes ``<root>/user_config/app/1.0``. Every thread of the
|
|
40
40
|
current process sees the change, and subprocesses do not.
|
|
41
41
|
|
|
42
|
+
On Unix, ``use_site_for_root`` is ignored inside the context so user and site directories keep separate kinds.
|
|
43
|
+
|
|
42
44
|
:param root: directory that holds the redirected directories
|
|
43
45
|
|
|
44
46
|
:returns: ``root`` as a :class:`~pathlib.Path`
|
|
@@ -51,11 +53,11 @@ def isolated_dirs(root: str | os.PathLike[str]) -> Generator[Path, None, None]:
|
|
|
51
53
|
)
|
|
52
54
|
for name in PlatformDirsABC.__abstractmethods__
|
|
53
55
|
}
|
|
54
|
-
#
|
|
56
|
+
# Base site lists follow the redirected dirs, and disabling root redirection keeps user and site kinds separate.
|
|
55
57
|
patches |= {
|
|
56
58
|
name: value
|
|
57
59
|
for name, value in vars(PlatformDirsABC).items()
|
|
58
|
-
if name.startswith("_site_") and name.endswith("_dirs")
|
|
60
|
+
if name == "_use_site" or (name.startswith("_site_") and name.endswith("_dirs"))
|
|
59
61
|
}
|
|
60
62
|
cls = platformdirs.PlatformDirs
|
|
61
63
|
saved = {name: vars(cls)[name] for name in patches if name in vars(cls)}
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '4.13.
|
|
22
|
-
__version_tuple__ = version_tuple = (4, 13,
|
|
21
|
+
__version__ = version = '4.13.4'
|
|
22
|
+
__version_tuple__ = version_tuple = (4, 13, 4)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -9,6 +9,7 @@ from functools import cache
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import TYPE_CHECKING, Final
|
|
11
11
|
|
|
12
|
+
from ._xdg import _expand_user
|
|
12
13
|
from .api import PlatformDirsABC
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
@@ -139,7 +140,7 @@ class Windows(PlatformDirsABC): # ruff:ignore[too-many-public-methods]
|
|
|
139
140
|
@property
|
|
140
141
|
def user_projects_dir(self) -> str:
|
|
141
142
|
r"""Projects directory tied to the user, e.g. ``%USERPROFILE%\Projects``."""
|
|
142
|
-
return os.path.normpath(
|
|
143
|
+
return os.path.normpath(_expand_user("~/Projects"))
|
|
143
144
|
|
|
144
145
|
@property
|
|
145
146
|
def user_publicshare_dir(self) -> str:
|
|
@@ -341,3 +341,29 @@ def test_android_opinion_subdir_created_private(
|
|
|
341
341
|
mocker.patch("platformdirs.android._android_folder", return_value=str(tmp_path), autospec=True)
|
|
342
342
|
subdir = Path(getattr(Android(appname="app", ensure_exists=True), prop)).name
|
|
343
343
|
assert modes(tmp_path) == {"cache": 0o700, "cache/app": 0o700, f"cache/app/{subdir}": 0o700}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@pytest.mark.usefixtures("_clear_android_caches")
|
|
347
|
+
@pytest.mark.parametrize(
|
|
348
|
+
"path",
|
|
349
|
+
[
|
|
350
|
+
pytest.param("/data/data/org.example.app/filesystem", id="internal-prefix"),
|
|
351
|
+
pytest.param("/data/user/10/org.example.app/files-backup/lib", id="secondary-user-prefix"),
|
|
352
|
+
pytest.param("/data/data/org.example.app/files\n", id="internal-newline"),
|
|
353
|
+
pytest.param(
|
|
354
|
+
"/mnt/expand/8e06fc2f-a86a-44e8-81ce-109e0eedd5ed/user/10/org.example.app/filesystem",
|
|
355
|
+
id="adopted-prefix",
|
|
356
|
+
),
|
|
357
|
+
pytest.param(
|
|
358
|
+
"/mnt/expand/8e06fc2f-a86a-44e8-81ce-109e0eedd5ed/user/10/org.example.app/files\n",
|
|
359
|
+
id="adopted-newline",
|
|
360
|
+
),
|
|
361
|
+
],
|
|
362
|
+
)
|
|
363
|
+
def test_android_folder_requires_files_segment(
|
|
364
|
+
mocker: MockerFixture, monkeypatch: pytest.MonkeyPatch, path: str
|
|
365
|
+
) -> None:
|
|
366
|
+
mocker.patch.dict(sys.modules, {"jnius": None})
|
|
367
|
+
monkeypatch.setattr(sys, "path", [path])
|
|
368
|
+
with pytest.raises(RuntimeError, match=r"^cannot find the Android app folder"):
|
|
369
|
+
_ = Android().user_data_dir
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
|
+
import re
|
|
4
5
|
import sys
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import TYPE_CHECKING, Any
|
|
@@ -124,7 +125,7 @@ def test_ios_ensure_exists_without_home_creates_nothing(
|
|
|
124
125
|
monkeypatch.delenv("HOME", raising=False)
|
|
125
126
|
mocker.patch.object(pwd, "getpwuid", side_effect=KeyError("getpwuid(): uid not found"))
|
|
126
127
|
monkeypatch.chdir(tmp_path)
|
|
127
|
-
with pytest.raises(RuntimeError, match=r"^could not determine the home directory
|
|
128
|
+
with pytest.raises(RuntimeError, match=r"^could not determine the home directory"):
|
|
128
129
|
_ = IOS(appname="app", ensure_exists=True).user_data_dir
|
|
129
130
|
assert list(tmp_path.iterdir()) == []
|
|
130
131
|
|
|
@@ -141,3 +142,22 @@ def test_ios_ensure_exists_without_home_creates_nothing(
|
|
|
141
142
|
def test_ios_ignores_xdg_variables(monkeypatch: pytest.MonkeyPatch, container: Path, env_var: str, func: str) -> None:
|
|
142
143
|
monkeypatch.setenv(env_var, "/xdg")
|
|
143
144
|
assert Path(getattr(IOS(), func)).is_relative_to(container)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@pytest.mark.usefixtures("_unknown_home")
|
|
148
|
+
@pytest.mark.parametrize(
|
|
149
|
+
("prop", "path"),
|
|
150
|
+
[
|
|
151
|
+
pytest.param("user_data_dir", "~/Library/Application Support", id="data"),
|
|
152
|
+
pytest.param("user_config_dir", "~/Library/Application Support", id="config"),
|
|
153
|
+
pytest.param("user_cache_dir", "~/Library/Caches", id="cache"),
|
|
154
|
+
pytest.param("user_log_dir", "~/Library/Logs", id="log"),
|
|
155
|
+
pytest.param("user_runtime_dir", "~/tmp", id="runtime"),
|
|
156
|
+
pytest.param("user_documents_dir", "~/Documents", id="documents"),
|
|
157
|
+
pytest.param("user_applications_dir", "~/Applications", id="applications"),
|
|
158
|
+
pytest.param("user_fonts_dir", "~/Library/Fonts", id="fonts"),
|
|
159
|
+
],
|
|
160
|
+
)
|
|
161
|
+
def test_without_home_ios_dir_raises(prop: str, path: str) -> None:
|
|
162
|
+
with pytest.raises(RuntimeError, match=re.escape(f"could not determine the home directory for {path!r}")):
|
|
163
|
+
_ = getattr(IOS(appname="app", version="1.0"), prop)
|
|
@@ -10,6 +10,7 @@ import pytest
|
|
|
10
10
|
import platformdirs
|
|
11
11
|
from platformdirs.android import Android
|
|
12
12
|
from platformdirs.testing import isolated_dirs
|
|
13
|
+
from platformdirs.unix import Unix
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from collections.abc import Callable
|
|
@@ -141,3 +142,57 @@ def test_isolated_dirs_nested_restores_outer(tmp_path: Path) -> None:
|
|
|
141
142
|
with isolated_dirs(tmp_path / "inner"):
|
|
142
143
|
pass
|
|
143
144
|
assert platformdirs.user_data_path("app") == tmp_path / "outer" / "user_data" / "app"
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@pytest.mark.usefixtures("_unix_root")
|
|
148
|
+
@pytest.mark.parametrize(
|
|
149
|
+
("kind", "suffix"),
|
|
150
|
+
[
|
|
151
|
+
pytest.param("user_data", "app/1.0", id="data"),
|
|
152
|
+
pytest.param("user_config", "app/1.0", id="config"),
|
|
153
|
+
pytest.param("user_preference", "app/1.0", id="preference"),
|
|
154
|
+
pytest.param("user_applications", "", id="applications"),
|
|
155
|
+
],
|
|
156
|
+
)
|
|
157
|
+
@pytest.mark.parametrize("multipath", [pytest.param(False, id="single"), pytest.param(True, id="multiple")])
|
|
158
|
+
def test_isolated_dirs_root_paths_follow_redirected_dirs(
|
|
159
|
+
tmp_path: Path, kind: str, suffix: str, multipath: bool
|
|
160
|
+
) -> None:
|
|
161
|
+
dirs = Unix("app", version="1.0", multipath=multipath, use_site_for_root=True)
|
|
162
|
+
expected = tmp_path / kind / suffix
|
|
163
|
+
with isolated_dirs(tmp_path):
|
|
164
|
+
assert getattr(dirs, f"{kind}_dir") == str(expected)
|
|
165
|
+
assert getattr(dirs, f"{kind}_path") == expected
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@pytest.mark.usefixtures("_unix_root")
|
|
169
|
+
def test_isolated_dirs_root_iter_config_paths(tmp_path: Path) -> None:
|
|
170
|
+
with isolated_dirs(tmp_path):
|
|
171
|
+
assert list(Unix("app", use_site_for_root=True).iter_config_paths()) == [
|
|
172
|
+
tmp_path / "user_config/app",
|
|
173
|
+
tmp_path / "site_config/app",
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@pytest.mark.usefixtures("_unix_root")
|
|
178
|
+
def test_isolated_dirs_restores_root_redirection(tmp_path: Path, mocker: MockerFixture) -> None:
|
|
179
|
+
mocker.patch.dict(os.environ, {"XDG_CONFIG_HOME": "/user", "XDG_CONFIG_DIRS": "/site"})
|
|
180
|
+
dirs = Unix("app", use_site_for_root=True)
|
|
181
|
+
with isolated_dirs(tmp_path):
|
|
182
|
+
pass
|
|
183
|
+
assert dirs.user_config_dir == dirs.site_config_dir
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@pytest.mark.usefixtures("_unix_root")
|
|
187
|
+
def test_isolated_dirs_nested_root_restores_after_exception(tmp_path: Path) -> None:
|
|
188
|
+
dirs = Unix("app", use_site_for_root=True)
|
|
189
|
+
with isolated_dirs(tmp_path):
|
|
190
|
+
with pytest.raises(LookupError), isolated_dirs(tmp_path / "inner"):
|
|
191
|
+
raise LookupError
|
|
192
|
+
assert dirs.user_config_path == tmp_path / "user_config/app"
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@pytest.fixture
|
|
196
|
+
def _unix_root(mocker: MockerFixture) -> None:
|
|
197
|
+
mocker.patch("platformdirs.PlatformDirs", Unix)
|
|
198
|
+
mocker.patch("platformdirs.unix.getuid", return_value=0)
|
|
@@ -148,6 +148,14 @@ def test_get_win_folder_from_env_vars_public_fallback(mocker: MockerFixture, env
|
|
|
148
148
|
assert get_win_folder_from_env_vars("CSIDL_PUBLIC") == str(Path("C:/Users/Public"))
|
|
149
149
|
|
|
150
150
|
|
|
151
|
+
def test_user_projects_dir_raises_without_home(mocker: MockerFixture) -> None:
|
|
152
|
+
# os.path.expanduser leaves the tilde in place when the home is unknown (only Path.expanduser raises),
|
|
153
|
+
# so the Projects directory must not come back as a literal ~ path.
|
|
154
|
+
mocker.patch.object(os.path, "expanduser", return_value="~/Projects")
|
|
155
|
+
with pytest.raises(RuntimeError, match=r"^could not determine the home directory for '~/Projects'"):
|
|
156
|
+
_ = Windows().user_projects_dir
|
|
157
|
+
|
|
158
|
+
|
|
151
159
|
def test_roaming_uses_appdata(mocker: MockerFixture) -> None:
|
|
152
160
|
mock = mocker.patch("platformdirs.windows.get_win_folder", side_effect=lambda csidl: _WIN_FOLDERS[csidl])
|
|
153
161
|
_result = Windows(appname="foo", roaming=True).user_data_dir
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|