Skip to content

Commit 078bc61

Browse files
✨ feat: add user_publicshare_dir, user_templates_dir, user_fonts_dir, user_preference_dir (#491)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent d279747 commit 078bc61

18 files changed

Lines changed: 600 additions & 18 deletions

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,26 @@ user_config_path("MyApp", "MyCompany") # returns pathlib.Path
4545

4646
## Directory types
4747

48+
**Application directories** — scoped to your app name and version:
49+
4850
- **Data**: Persistent application data (`user_data_dir`, `site_data_dir`)
4951
- **Config**: Configuration files and settings (`user_config_dir`, `site_config_dir`)
52+
- **Preference**: User preferences, distinct from config on macOS (`user_preference_dir`)
5053
- **Cache**: Cached data that can be regenerated (`user_cache_dir`, `site_cache_dir`)
5154
- **State**: Non-essential runtime state like window positions (`user_state_dir`, `site_state_dir`)
5255
- **Logs**: Log files (`user_log_dir`, `site_log_dir`)
5356
- **Runtime**: Runtime files like sockets and PIDs (`user_runtime_dir`, `site_runtime_dir`)
5457

55-
Each type has both `user_*` (per-user, writable) and `site_*` (system-wide, read-only for users) variants.
58+
App dirs have both `user_*` (per-user, writable) and `site_*` (system-wide, read-only) variants where applicable.
59+
60+
**User media directories** — standard user-facing folders, not scoped to app name:
61+
62+
- **Documents** (`user_documents_dir`), **Downloads** (`user_downloads_dir`)
63+
- **Pictures** (`user_pictures_dir`), **Videos** (`user_videos_dir`), **Music** (`user_music_dir`)
64+
- **Desktop** (`user_desktop_dir`), **Projects** (`user_projects_dir`)
65+
- **Public share** (`user_publicshare_dir`), **Templates** (`user_templates_dir`)
66+
- **Fonts** (`user_fonts_dir`) — user-writable font installation directory
67+
- **Executable** (`user_bin_dir`, `site_bin_dir`), **Applications** (`user_applications_dir`, `site_applications_dir`)
5668

5769
## Documentation
5870

docs/api.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,42 @@ See also: :ref:`platforms:``user_projects_dir```
150150

151151
.. autofunction:: platformdirs.user_projects_path
152152

153+
User public share directory
154+
===========================
155+
156+
See also: :ref:`platforms:``user_publicshare_dir```
157+
158+
.. autofunction:: platformdirs.user_publicshare_dir
159+
160+
.. autofunction:: platformdirs.user_publicshare_path
161+
162+
User templates directory
163+
========================
164+
165+
See also: :ref:`platforms:``user_templates_dir```
166+
167+
.. autofunction:: platformdirs.user_templates_dir
168+
169+
.. autofunction:: platformdirs.user_templates_path
170+
171+
User fonts directory
172+
====================
173+
174+
See also: :ref:`platforms:``user_fonts_dir```
175+
176+
.. autofunction:: platformdirs.user_fonts_dir
177+
178+
.. autofunction:: platformdirs.user_fonts_path
179+
180+
User preference directory
181+
=========================
182+
183+
See also: :ref:`platforms:``user_preference_dir```
184+
185+
.. autofunction:: platformdirs.user_preference_dir
186+
187+
.. autofunction:: platformdirs.user_preference_path
188+
153189
********************
154190
Shared directories
155191
********************

docs/explanation.rst

Lines changed: 160 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,74 @@ purpose. Application authors write platform-agnostic code while end users get pa
1717
Choosing the right directory
1818
******************************
1919

20-
``platformdirs`` provides different directory types for different kinds of data. Choose based on the data's purpose and
21-
lifetime.
20+
The first question is always: who owns this data? **App-internal data** — databases, caches, config files, logs — goes
21+
in an app dir scoped to your app name. **User-facing data** — files the user would browse to directly — goes in a media
22+
dir that sits alongside their documents, music, and photos.
23+
24+
Within app dirs, the next question is whether the data is essential. If it can be regenerated, use ``cache`` (fast
25+
lookups) or ``runtime`` (session-only sockets and PIDs). If it is important but not critical, use ``state`` (window
26+
positions, recent files). For settings use ``config``; on macOS, ``preference`` gives you the separate
27+
``~/Library/Preferences`` location that Apple convention expects. Use ``data`` for everything else that must survive app
28+
updates.
29+
30+
Within media dirs, pick the folder that matches the file's type from the user's perspective — not what your app does
31+
with it. A font your app installs for the user goes in ``fonts``, not ``data``.
2232

2333
.. mermaid::
2434

2535
flowchart TD
26-
A[What kind of data?] --> B{Can it be deleted<br/>without data loss?}
27-
B -- Yes --> C{Is it used to<br/>speed things up?}
28-
C -- Yes --> D[**cache** dir]
29-
C -- No --> E{Is it temporary<br/>for this session?}
30-
E -- Yes --> F[**runtime** dir]
31-
E -- No --> G[**state** dir]
32-
B -- No --> H{Is it a<br/>user preference?}
33-
H -- Yes --> I[**config** dir]
34-
H -- No --> J{Is it a<br/>log file?}
35-
J -- Yes --> K[**log** dir]
36-
J -- No --> L[**data** dir]
36+
A([What kind of data?]) --> B{Belongs to the app<br/>or to the user?}
37+
38+
B -- App internal --> C{Can it be deleted<br/>without data loss?}
39+
C -- Yes --> D{Speeds things up?}
40+
D -- Yes --> CACHE[cache dir]
41+
D -- No --> E{Temporary for<br/>this session only?}
42+
E -- Yes --> RUNTIME[runtime dir]
43+
E -- No --> STATE[state dir]
44+
C -- No --> F{What kind?}
45+
F -- Settings / options --> CONFIG[config dir]
46+
F -- macOS preferences --> PREF[preference dir]
47+
F -- Log file --> LOG[log dir]
48+
F -- Everything else --> DATA[data dir]
49+
50+
B -- User-facing file --> G{File type?}
51+
G -- Document / report --> DOC[documents dir]
52+
G -- Downloaded content --> DL[downloads dir]
53+
G -- Image --> PIC[pictures dir]
54+
G -- Video --> VID[videos dir]
55+
G -- Audio --> MUS[music dir]
56+
G -- Font --> FONT[fonts dir]
57+
G -- Template --> TMPL[templates dir]
58+
G -- Project / code --> PROJ[projects dir]
59+
G -- Desktop shortcut --> DESK[desktop dir]
60+
G -- Share with others --> PUB[publicshare dir]
61+
62+
style A fill:#1e40af,stroke:#1e3a8a,color:#fff
63+
style B fill:#d97706,stroke:#b45309,color:#fff
64+
style C fill:#d97706,stroke:#b45309,color:#fff
65+
style D fill:#d97706,stroke:#b45309,color:#fff
66+
style E fill:#d97706,stroke:#b45309,color:#fff
67+
style F fill:#d97706,stroke:#b45309,color:#fff
68+
style G fill:#d97706,stroke:#b45309,color:#fff
69+
70+
style CACHE fill:#2563eb,stroke:#1d4ed8,color:#fff
71+
style RUNTIME fill:#2563eb,stroke:#1d4ed8,color:#fff
72+
style STATE fill:#2563eb,stroke:#1d4ed8,color:#fff
73+
style CONFIG fill:#2563eb,stroke:#1d4ed8,color:#fff
74+
style PREF fill:#7c3aed,stroke:#6d28d9,color:#fff
75+
style LOG fill:#2563eb,stroke:#1d4ed8,color:#fff
76+
style DATA fill:#2563eb,stroke:#1d4ed8,color:#fff
77+
78+
style DOC fill:#16a34a,stroke:#15803d,color:#fff
79+
style DL fill:#16a34a,stroke:#15803d,color:#fff
80+
style PIC fill:#16a34a,stroke:#15803d,color:#fff
81+
style VID fill:#16a34a,stroke:#15803d,color:#fff
82+
style MUS fill:#16a34a,stroke:#15803d,color:#fff
83+
style FONT fill:#16a34a,stroke:#15803d,color:#fff
84+
style TMPL fill:#16a34a,stroke:#15803d,color:#fff
85+
style PROJ fill:#16a34a,stroke:#15803d,color:#fff
86+
style DESK fill:#16a34a,stroke:#15803d,color:#fff
87+
style PUB fill:#16a34a,stroke:#15803d,color:#fff
3788

3889
Data directories
3990
================
@@ -141,6 +192,102 @@ Use ``user_log_dir`` and ``site_log_dir`` for application logs:
141192
format="%(asctime)s - %(levelname)s - %(message)s",
142193
)
143194
195+
************************
196+
User media directories
197+
************************
198+
199+
Unlike app dirs (data, config, cache, etc.), media dirs are **not** scoped to the app name. They point to standard
200+
user-facing folders that exist independently of any particular application. Use them when your app needs to read from or
201+
save into a folder the user already expects — not when storing application state.
202+
203+
The distinction matters:
204+
205+
- ``user_data_dir("MyApp")`` → ``~/.local/share/MyApp`` — your app's private storage
206+
- ``user_documents_dir()`` → ``~/Documents`` — the user's document library
207+
208+
On Linux, media dirs are defined by the `XDG user-dirs specification
209+
<https://www.freedesktop.org/wiki/Software/xdg-user-dirs/>`_ and stored in ``~/.config/user-dirs.dirs``. The
210+
``xdg-user-dirs`` tool lets users relocate them. Set the corresponding environment variable (``XDG_DOCUMENTS_DIR``,
211+
``XDG_DOWNLOAD_DIR``, etc.) to override on a per-session basis. On macOS and Windows, ``platformdirs`` returns the
212+
platform-conventional location.
213+
214+
Media and user-facing directories
215+
=================================
216+
217+
Use these when your app saves or opens files the user should see in their own folders:
218+
219+
``user_documents_dir`` (``XDG_DOCUMENTS_DIR``)
220+
Exported reports, user-authored files. Save here when the file is *for the user*, not the app.
221+
222+
``user_downloads_dir`` (``XDG_DOWNLOAD_DIR``)
223+
Files fetched from the internet at the user's request.
224+
225+
``user_pictures_dir`` / ``user_videos_dir`` / ``user_music_dir``
226+
Platform media libraries. Use when importing or exporting to the user's existing collection.
227+
228+
``user_desktop_dir`` (``XDG_DESKTOP_DIR``)
229+
Shortcut files and launchers. Rarely needed directly in code.
230+
231+
``user_projects_dir`` (``XDG_PROJECTS_DIR``)
232+
Root directory for the user's coding projects. `Recently added to xdg-user-dirs
233+
<https://gitlab.freedesktop.org/xdg/xdg-user-dirs/-/commit/217cae71c620ed2b3ed2936256ece68defccc6ab>`_.
234+
235+
``user_publicshare_dir`` (``XDG_PUBLICSHARE_DIR``)
236+
Files shared with other local accounts. On Windows this is the machine-wide ``C:\Users\Public`` (``%PUBLIC%``), not
237+
a per-user directory.
238+
239+
.. code-block:: python
240+
241+
from platformdirs import user_documents_path
242+
243+
report = user_documents_path() / "report.pdf"
244+
245+
Do not use these to store application state or config — if the file would confuse the user when they browse the folder,
246+
it belongs in ``user_data_dir`` instead.
247+
248+
Templates
249+
=========
250+
251+
``user_templates_dir`` (``XDG_TEMPLATES_DIR``) points to the folder used by file managers for new-file templates. macOS
252+
has no platform-defined templates directory; ``~/Templates`` is returned as a pragmatic fallback.
253+
254+
Fonts
255+
=====
256+
257+
``user_fonts_dir`` points to the per-user font installation directory:
258+
259+
- **Linux**: ``$XDG_DATA_HOME/fonts`` (default ``~/.local/share/fonts``) — derived from ``$XDG_DATA_HOME``, not a
260+
dedicated env var. See the `XDG Base Directory Specification
261+
<https://specifications.freedesktop.org/basedir/latest/>`_.
262+
- **macOS**: ``~/Library/Fonts``
263+
- **Windows**: ``%LOCALAPPDATA%\Microsoft\Windows\Fonts`` — the per-user font location added in Windows 10
264+
265+
.. code-block:: python
266+
267+
import shutil
268+
from platformdirs import user_fonts_path
269+
270+
font_dir = user_fonts_path()
271+
font_dir.mkdir(parents=True, exist_ok=True)
272+
shutil.copy("MyFont.ttf", font_dir / "MyFont.ttf")
273+
274+
**********************
275+
Preference directory
276+
**********************
277+
278+
``user_preference_dir`` is meaningful mainly on macOS, where Apple's conventions distinguish two separate locations:
279+
280+
- ``~/Library/Application Support/AppName`` — long-term application data, databases, plug-ins
281+
- ``~/Library/Preferences/AppName`` — user-adjustable preference files (historically ``.plist``)
282+
283+
On Linux and Windows, ``user_preference_dir`` is an alias for ``user_config_dir`` — the XDG and Windows conventions make
284+
no such distinction. On Android, it also aliases ``user_config_dir``.
285+
286+
Use ``user_preference_dir`` when you specifically need to follow Apple's `File System Programming Guide
287+
<https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html>`_
288+
and store preference files in ``~/Library/Preferences``. For most cross-platform applications ``user_config_dir`` is
289+
sufficient.
290+
144291
**************************
145292
User vs site directories
146293
**************************

docs/index.rst

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,30 @@ and Android.
4444
Keep multiple app versions side by side with the ``version`` parameter.
4545

4646
.. toctree::
47-
:maxdepth: 2
48-
:caption: Contents
47+
:hidden:
48+
:caption: Tutorial
4949

5050
tutorial
51+
52+
.. toctree::
53+
:hidden:
54+
:caption: How-to guides
55+
5156
howto
52-
explanation
57+
58+
.. toctree::
59+
:hidden:
60+
:caption: Reference
61+
5362
parameters
5463
api
5564
platforms
65+
66+
.. toctree::
67+
:hidden:
68+
:caption: Explanation
69+
70+
explanation
5671
changelog
5772

5873
********************

0 commit comments

Comments
 (0)