Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-platformdirs for openSUSE:Factory checked in at 2021-10-25 15:16:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-platformdirs (Old) and /work/SRC/openSUSE:Factory/.python-platformdirs.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-platformdirs" Mon Oct 25 15:16:48 2021 rev:2 rq:922953 version:2.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-platformdirs/python-platformdirs.changes 2021-08-04 22:29:23.889764419 +0200 +++ /work/SRC/openSUSE:Factory/.python-platformdirs.new.1890/python-platformdirs.changes 2021-10-25 15:17:07.505664066 +0200 @@ -1,0 +2,8 @@ +Sun Oct 3 19:04:59 UTC 2021 - Ben Greiner <c...@bnavigator.de> + +- Update to version 2.4.0 + * Add user_documents_dir + * Add user_runtime_dir and its path-returning equivalent (#37) +- Fix egg-info version: build requires setuptools_scm >= 5 + +------------------------------------------------------------------- Old: ---- platformdirs-2.2.0.tar.gz New: ---- platformdirs-2.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-platformdirs.spec ++++++ --- /var/tmp/diff_new_pack.e5mmiu/_old 2021-10-25 15:17:08.041664401 +0200 +++ /var/tmp/diff_new_pack.e5mmiu/_new 2021-10-25 15:17:08.045664404 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-platformdirs -Version: 2.2.0 +Version: 2.4.0 Release: 0 Summary: Module for determining appropriate platform-specific dirs License: MIT @@ -31,8 +31,8 @@ Patch0: no-furo.patch BuildRequires: %{python_module appdirs == 1.4.4} BuildRequires: %{python_module pytest >= 6} -BuildRequires: %{python_module pytest-cov >= 2.7} BuildRequires: %{python_module pytest-mock >= 3.6} +BuildRequires: %{python_module setuptools_scm >= 5} BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -56,6 +56,7 @@ %build %python_build + PYTHONPATH=src sphinx-build -b html docs/ docs/build/html rm -r docs/build/html/.{buildinfo,doctrees} @@ -64,12 +65,14 @@ %python_expand %fdupes %{buildroot}%{$python_sitelib} %check +rm tox.ini %pytest %files %{python_files} %doc CHANGES.rst README.rst %license LICENSE.txt -%{python_sitelib}/platformdirs* +%{python_sitelib}/platformdirs +%{python_sitelib}/platformdirs-%{version}*-info %files -n %{name}-doc %doc docs/build/html/ ++++++ platformdirs-2.2.0.tar.gz -> platformdirs-2.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/.github/workflows/check.yml new/platformdirs-2.4.0/.github/workflows/check.yml --- old/platformdirs-2.2.0/.github/workflows/check.yml 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/.github/workflows/check.yml 2021-09-25 22:45:42.000000000 +0200 @@ -30,7 +30,7 @@ - Windows - MacOs py: - - "3.10.0-alpha.7" + - "3.10.0-rc.1" - "3.9" - "3.8" - "3.7" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/.pre-commit-config.yaml new/platformdirs-2.4.0/.pre-commit-config.yaml --- old/platformdirs-2.2.0/.pre-commit-config.yaml 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/.pre-commit-config.yaml 2021-09-25 22:45:42.000000000 +0200 @@ -10,15 +10,15 @@ - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/asottile/pyupgrade - rev: v2.21.0 + rev: v2.25.0 hooks: - id: pyupgrade - repo: https://github.com/PyCQA/isort - rev: 5.9.2 + rev: 5.9.3 hooks: - id: isort - repo: https://github.com/psf/black - rev: 21.6b0 + rev: 21.8b0 hooks: - id: black args: [--safe] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/CHANGES.rst new/platformdirs-2.4.0/CHANGES.rst --- old/platformdirs-2.2.0/CHANGES.rst 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/CHANGES.rst 2021-09-25 22:45:42.000000000 +0200 @@ -1,6 +1,10 @@ platformdirs Changelog ====================== +platformdirs 2.3.0 +------------------ +- Add ``user_runtime_dir`` and its path-returning equivalent (#37) + platformdirs 2.2.0 ------------------ - Unix: Fallback to default if XDG environment variable is empty diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/PKG-INFO new/platformdirs-2.4.0/PKG-INFO --- old/platformdirs-2.2.0/PKG-INFO 2021-07-29 13:51:28.040797200 +0200 +++ new/platformdirs-2.4.0/PKG-INFO 2021-09-25 22:45:52.550757400 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: platformdirs -Version: 2.2.0 +Version: 2.4.0 Summary: A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir". Home-page: https://github.com/platformdirs/platformdirs Maintainer: Bern??t G??bor, Julian Berman, Ofek Lev, Ronny Pfannschmidt @@ -32,7 +32,7 @@ Provides-Extra: test License-File: LICENSE.txt -the problem +The problem =========== .. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg @@ -74,6 +74,8 @@ - site data dir (``site_data_dir``) - site config dir (``site_config_dir``) - user log dir (``user_log_dir``) +- user documents dir (``user_documents_dir``) +- user runtime dir (``user_runtime_dir``) And also: @@ -99,6 +101,10 @@ '/Users/trentm/Library/Caches/SuperApp' >>> user_log_dir(appname, appauthor) '/Users/trentm/Library/Logs/SuperApp' + >>> user_documents_dir() + '/Users/trentm/Documents' + >>> user_runtime_dir(appname, appauthor) + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp' On Windows 7: @@ -115,6 +121,10 @@ 'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache' >>> user_log_dir(appname, appauthor) 'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs' + >>> user_documents_dir() + 'C:\\Users\\trentm\\Documents' + >>> user_runtime_dir(appname, appauthor) + 'C:\\Users\\trentm\\AppData\\Local\\Temp\\Acme\\SuperApp' On Linux: @@ -135,6 +145,10 @@ '/home/trentm/.cache/SuperApp/log' >>> user_config_dir(appname) '/home/trentm/.config/SuperApp' + >>> user_documents_dir() + '/home/trentm/Documents' + >>> user_runtime_dir(appname, appauthor) + '/run/user/{os.getuid()}/SuperApp' >>> site_config_dir(appname) '/etc/xdg/SuperApp' >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc' @@ -154,7 +168,10 @@ '/data/data/com.termux/cache/SuperApp/log' >>> user_config_dir(appname) '/data/data/com.termux/shared_prefs/SuperApp' - + >>> user_documents_dir() + '/storage/emulated/0/Documents' + >>> user_runtime_dir(appname, appauthor) + '/data/data/com.termux/cache/SuperApp/tmp' ``PlatformDirs`` for convenience ================================ @@ -171,6 +188,10 @@ '/Users/trentm/Library/Caches/SuperApp' >>> dirs.user_log_dir '/Users/trentm/Library/Logs/SuperApp' + >>> dirs.user_documents_dir + '/Users/trentm/Documents' + >>> dirs.user_runtime_dir + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp' Per-version isolation ===================== @@ -189,6 +210,10 @@ '/Users/trentm/Library/Caches/SuperApp/1.0' >>> dirs.user_log_dir '/Users/trentm/Library/Logs/SuperApp/1.0' + >>> dirs.user_documents_dir + '/Users/trentm/Documents' + >>> dirs.user_runtime_dir + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0' Be wary of using this for configuration files though; you'll need to handle migrating configuration files manually. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/README.rst new/platformdirs-2.4.0/README.rst --- old/platformdirs-2.2.0/README.rst 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/README.rst 2021-09-25 22:45:42.000000000 +0200 @@ -1,4 +1,4 @@ -the problem +The problem =========== .. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg @@ -40,6 +40,8 @@ - site data dir (``site_data_dir``) - site config dir (``site_config_dir``) - user log dir (``user_log_dir``) +- user documents dir (``user_documents_dir``) +- user runtime dir (``user_runtime_dir``) And also: @@ -65,6 +67,10 @@ '/Users/trentm/Library/Caches/SuperApp' >>> user_log_dir(appname, appauthor) '/Users/trentm/Library/Logs/SuperApp' + >>> user_documents_dir() + '/Users/trentm/Documents' + >>> user_runtime_dir(appname, appauthor) + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp' On Windows 7: @@ -81,6 +87,10 @@ 'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache' >>> user_log_dir(appname, appauthor) 'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs' + >>> user_documents_dir() + 'C:\\Users\\trentm\\Documents' + >>> user_runtime_dir(appname, appauthor) + 'C:\\Users\\trentm\\AppData\\Local\\Temp\\Acme\\SuperApp' On Linux: @@ -101,6 +111,10 @@ '/home/trentm/.cache/SuperApp/log' >>> user_config_dir(appname) '/home/trentm/.config/SuperApp' + >>> user_documents_dir() + '/home/trentm/Documents' + >>> user_runtime_dir(appname, appauthor) + '/run/user/{os.getuid()}/SuperApp' >>> site_config_dir(appname) '/etc/xdg/SuperApp' >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc' @@ -120,7 +134,10 @@ '/data/data/com.termux/cache/SuperApp/log' >>> user_config_dir(appname) '/data/data/com.termux/shared_prefs/SuperApp' - + >>> user_documents_dir() + '/storage/emulated/0/Documents' + >>> user_runtime_dir(appname, appauthor) + '/data/data/com.termux/cache/SuperApp/tmp' ``PlatformDirs`` for convenience ================================ @@ -137,6 +154,10 @@ '/Users/trentm/Library/Caches/SuperApp' >>> dirs.user_log_dir '/Users/trentm/Library/Logs/SuperApp' + >>> dirs.user_documents_dir + '/Users/trentm/Documents' + >>> dirs.user_runtime_dir + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp' Per-version isolation ===================== @@ -155,6 +176,10 @@ '/Users/trentm/Library/Caches/SuperApp/1.0' >>> dirs.user_log_dir '/Users/trentm/Library/Logs/SuperApp/1.0' + >>> dirs.user_documents_dir + '/Users/trentm/Documents' + >>> dirs.user_runtime_dir + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0' Be wary of using this for configuration files though; you'll need to handle migrating configuration files manually. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/docs/api.rst new/platformdirs-2.4.0/docs/api.rst --- old/platformdirs-2.2.0/docs/api.rst 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/docs/api.rst 2021-09-25 22:45:42.000000000 +0200 @@ -36,6 +36,18 @@ .. autofunction:: platformdirs.user_log_dir .. autofunction:: platformdirs.user_log_path +User documents directory +------------------------ + +.. autofunction:: platformdirs.user_documents_dir +.. autofunction:: platformdirs.user_documents_path + +Runtime directory +------------------- + +.. autofunction:: platformdirs.user_runtime_dir +.. autofunction:: platformdirs.user_runtime_path + Shared directories ~~~~~~~~~~~~~~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/__init__.py new/platformdirs-2.4.0/src/platformdirs/__init__.py --- old/platformdirs-2.2.0/src/platformdirs/__init__.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/__init__.py 2021-09-25 22:45:42.000000000 +0200 @@ -144,6 +144,29 @@ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_log_dir +def user_documents_dir() -> str: + """ + :returns: documents directory tied to the user + """ + return PlatformDirs().user_documents_dir + + +def user_runtime_dir( + appname: Optional[str] = None, + appauthor: Union[str, None, "Literal[False]"] = None, + version: Optional[str] = None, + opinion: bool = True, +) -> str: + """ + :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`. + :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`. + :param version: See `version <platformdirs.api.PlatformDirsABC.version>`. + :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`. + :returns: runtime directory tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_runtime_dir + + def user_data_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, @@ -256,6 +279,29 @@ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_log_path +def user_documents_path() -> Path: + """ + :returns: documents path tied to the user + """ + return PlatformDirs().user_documents_path + + +def user_runtime_path( + appname: Optional[str] = None, + appauthor: Union[str, None, "Literal[False]"] = None, + version: Optional[str] = None, + opinion: bool = True, +) -> Path: + """ + :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`. + :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`. + :param version: See `version <platformdirs.api.PlatformDirsABC.version>`. + :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`. + :returns: runtime path tied to the user + """ + return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_runtime_path + + __all__ = [ "__version__", "__version_info__", @@ -267,6 +313,8 @@ "user_cache_dir", "user_state_dir", "user_log_dir", + "user_documents_dir", + "user_runtime_dir", "site_data_dir", "site_config_dir", "user_data_path", @@ -274,6 +322,8 @@ "user_cache_path", "user_state_path", "user_log_path", + "user_documents_path", + "user_runtime_path", "site_data_path", "site_config_path", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/__main__.py new/platformdirs-2.4.0/src/platformdirs/__main__.py --- old/platformdirs-2.2.0/src/platformdirs/__main__.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/__main__.py 2021-09-25 22:45:42.000000000 +0200 @@ -6,6 +6,8 @@ "user_cache_dir", "user_state_dir", "user_log_dir", + "user_documents_dir", + "user_runtime_dir", "site_data_dir", "site_config_dir", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/android.py new/platformdirs-2.4.0/src/platformdirs/android.py --- old/platformdirs-2.2.0/src/platformdirs/android.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/android.py 2021-09-25 22:45:42.000000000 +0200 @@ -56,6 +56,24 @@ path = os.path.join(path, "log") return path + @property + def user_documents_dir(self) -> str: + """ + :return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents`` + """ + return _android_documents_folder() + + @property + def user_runtime_dir(self) -> str: + """ + :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it, + e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/tmp`` + """ + path = self.user_cache_dir + if self.opinion: + path = os.path.join(path, "tmp") + return path + @lru_cache(maxsize=1) def _android_folder() -> str: @@ -78,6 +96,22 @@ return result +@lru_cache(maxsize=1) +def _android_documents_folder() -> str: + """:return: documents folder for the Android OS""" + # Get directories with pyjnius + try: + from jnius import autoclass # noqa: SC200 + + Context = autoclass("android.content.Context") # noqa: SC200 + Environment = autoclass("android.os.Environment") + documents_dir: str = Context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + except Exception: + documents_dir = "/storage/emulated/0/Documents" + + return documents_dir + + __all__ = [ "Android", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/api.py new/platformdirs-2.4.0/src/platformdirs/api.py --- old/platformdirs-2.2.0/src/platformdirs/api.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/api.py 2021-09-25 22:45:42.000000000 +0200 @@ -100,6 +100,16 @@ """:return: log directory tied to the user""" @property + @abstractmethod + def user_documents_dir(self) -> str: + """:return: documents directory tied to the user""" + + @property + @abstractmethod + def user_runtime_dir(self) -> str: + """:return: runtime directory tied to the user""" + + @property def user_data_path(self) -> Path: """:return: data path tied to the user""" return Path(self.user_data_dir) @@ -133,3 +143,13 @@ def user_log_path(self) -> Path: """:return: log path tied to the user""" return Path(self.user_log_dir) + + @property + def user_documents_path(self) -> Path: + """:return: documents path tied to the user""" + return Path(self.user_documents_dir) + + @property + def user_runtime_path(self) -> Path: + """:return: runtime path tied to the user""" + return Path(self.user_runtime_dir) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/macos.py new/platformdirs-2.4.0/src/platformdirs/macos.py --- old/platformdirs-2.2.0/src/platformdirs/macos.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/macos.py 2021-09-25 22:45:42.000000000 +0200 @@ -46,6 +46,16 @@ """:return: log directory tied to the user, e.g. ``~/Library/Logs/$appname/$version``""" return self._append_app_name_and_version(os.path.expanduser("~/Library/Logs")) + @property + def user_documents_dir(self) -> str: + """:return: documents directory tied to the user, e.g. ``~/Documents``""" + return os.path.expanduser("~/Documents") + + @property + def user_runtime_dir(self) -> str: + """:return: runtime directory tied to the user, e.g. ``~/Library/Caches/TemporaryItems/$appname/$version``""" + return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches/TemporaryItems")) + __all__ = [ "MacOS", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/unix.py new/platformdirs-2.4.0/src/platformdirs/unix.py --- old/platformdirs-2.2.0/src/platformdirs/unix.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/unix.py 2021-09-25 22:45:42.000000000 +0200 @@ -1,8 +1,18 @@ import os +import sys +from configparser import ConfigParser from pathlib import Path +from typing import Optional from .api import PlatformDirsABC +if sys.platform.startswith("linux"): # pragma: no branch # no op check, only to please the type checker + from os import getuid +else: + + def getuid() -> int: + raise RuntimeError("should only be used on Linux") + class Unix(PlatformDirsABC): """ @@ -104,6 +114,30 @@ return path @property + def user_documents_dir(self) -> str: + """ + :return: documents directory tied to the user, e.g. ``~/Documents`` + """ + documents_dir = _get_user_dirs_folder("XDG_DOCUMENTS_DIR") + if documents_dir is None: + documents_dir = os.environ.get("XDG_DOCUMENTS_DIR", "").strip() + if not documents_dir: + documents_dir = os.path.expanduser("~/Documents") + + return documents_dir + + @property + def user_runtime_dir(self) -> str: + """ + :return: runtime directory tied to the user, e.g. ``/run/user/$(id -u)/$appname/$version`` or + ``$XDG_RUNTIME_DIR/$appname/$version`` + """ + path = os.environ.get("XDG_RUNTIME_DIR", "") + if not path.strip(): + path = f"/run/user/{getuid()}" + return self._append_app_name_and_version(path) + + @property def site_data_path(self) -> Path: """:return: data path shared by users. Only return first item, even if ``multipath`` is set to ``True``""" return self._first_item_as_path_if_multipath(self.site_data_dir) @@ -120,6 +154,27 @@ return Path(directory) +def _get_user_dirs_folder(key: str) -> Optional[str]: + """Return directory from user-dirs.dirs config file. See https://freedesktop.org/wiki/Software/xdg-user-dirs/""" + user_dirs_config_path = os.path.join(Unix().user_config_dir, "user-dirs.dirs") + if os.path.exists(user_dirs_config_path): + parser = ConfigParser() + + with open(user_dirs_config_path) as stream: + # Add fake section header, so ConfigParser doesn't complain + parser.read_string(f"[top]\n{stream.read()}") + + if key not in parser["top"]: + return None + + path = parser["top"][key].strip('"') + # Handle relative home paths + path = path.replace("$HOME", os.path.expanduser("~")) + return path + + return None + + __all__ = [ "Unix", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/version.py new/platformdirs-2.4.0/src/platformdirs/version.py --- old/platformdirs-2.2.0/src/platformdirs/version.py 2021-07-29 13:51:27.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/version.py 2021-09-25 22:45:52.000000000 +0200 @@ -1,4 +1,4 @@ """ Version information """ -__version__ = "2.2.0" -__version_info__ = (2, 2, 0) +__version__ = "2.4.0" +__version_info__ = (2, 4, 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs/windows.py new/platformdirs-2.4.0/src/platformdirs/windows.py --- old/platformdirs-2.2.0/src/platformdirs/windows.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs/windows.py 2021-09-25 22:45:42.000000000 +0200 @@ -80,9 +80,28 @@ path = os.path.join(path, "Logs") return path + @property + def user_documents_dir(self) -> str: + """ + :return: documents directory tied to the user e.g. ``%USERPROFILE%\\Documents`` + """ + return os.path.normpath(get_win_folder("CSIDL_PERSONAL")) + + @property + def user_runtime_dir(self) -> str: + """ + :return: runtime directory tied to the user, e.g. + ``%USERPROFILE%\\AppData\\Local\\Temp\\$appauthor\\$appname`` + """ + path = os.path.normpath(os.path.join(get_win_folder("CSIDL_LOCAL_APPDATA"), "Temp")) + return self._append_parts(path) + def get_win_folder_from_env_vars(csidl_name: str) -> str: """Get folder from environment variables.""" + if csidl_name == "CSIDL_PERSONAL": # does not have an environment name + return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Documents") + env_var_name = { "CSIDL_APPDATA": "APPDATA", "CSIDL_COMMON_APPDATA": "ALLUSERSPROFILE", @@ -107,6 +126,7 @@ "CSIDL_APPDATA": "AppData", "CSIDL_COMMON_APPDATA": "Common AppData", "CSIDL_LOCAL_APPDATA": "Local AppData", + "CSIDL_PERSONAL": "Personal", }.get(csidl_name) if shell_folder_name is None: raise ValueError(f"Unknown CSIDL name: {csidl_name}") @@ -124,6 +144,7 @@ "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, "CSIDL_LOCAL_APPDATA": 28, + "CSIDL_PERSONAL": 5, }.get(csidl_name) if csidl_const is None: raise ValueError(f"Unknown CSIDL name: {csidl_name}") @@ -132,12 +153,8 @@ windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) - has_high_char = False # Downgrade to short path name if it has highbit chars. - for c in buf: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: + # Downgrade to short path name if it has highbit chars. + if any(ord(c) > 255 for c in buf): buf2 = ctypes.create_unicode_buffer(1024) if windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): buf = buf2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/src/platformdirs.egg-info/PKG-INFO new/platformdirs-2.4.0/src/platformdirs.egg-info/PKG-INFO --- old/platformdirs-2.2.0/src/platformdirs.egg-info/PKG-INFO 2021-07-29 13:51:27.000000000 +0200 +++ new/platformdirs-2.4.0/src/platformdirs.egg-info/PKG-INFO 2021-09-25 22:45:52.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: platformdirs -Version: 2.2.0 +Version: 2.4.0 Summary: A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir". Home-page: https://github.com/platformdirs/platformdirs Maintainer: Bern??t G??bor, Julian Berman, Ofek Lev, Ronny Pfannschmidt @@ -32,7 +32,7 @@ Provides-Extra: test License-File: LICENSE.txt -the problem +The problem =========== .. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg @@ -74,6 +74,8 @@ - site data dir (``site_data_dir``) - site config dir (``site_config_dir``) - user log dir (``user_log_dir``) +- user documents dir (``user_documents_dir``) +- user runtime dir (``user_runtime_dir``) And also: @@ -99,6 +101,10 @@ '/Users/trentm/Library/Caches/SuperApp' >>> user_log_dir(appname, appauthor) '/Users/trentm/Library/Logs/SuperApp' + >>> user_documents_dir() + '/Users/trentm/Documents' + >>> user_runtime_dir(appname, appauthor) + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp' On Windows 7: @@ -115,6 +121,10 @@ 'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache' >>> user_log_dir(appname, appauthor) 'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs' + >>> user_documents_dir() + 'C:\\Users\\trentm\\Documents' + >>> user_runtime_dir(appname, appauthor) + 'C:\\Users\\trentm\\AppData\\Local\\Temp\\Acme\\SuperApp' On Linux: @@ -135,6 +145,10 @@ '/home/trentm/.cache/SuperApp/log' >>> user_config_dir(appname) '/home/trentm/.config/SuperApp' + >>> user_documents_dir() + '/home/trentm/Documents' + >>> user_runtime_dir(appname, appauthor) + '/run/user/{os.getuid()}/SuperApp' >>> site_config_dir(appname) '/etc/xdg/SuperApp' >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc' @@ -154,7 +168,10 @@ '/data/data/com.termux/cache/SuperApp/log' >>> user_config_dir(appname) '/data/data/com.termux/shared_prefs/SuperApp' - + >>> user_documents_dir() + '/storage/emulated/0/Documents' + >>> user_runtime_dir(appname, appauthor) + '/data/data/com.termux/cache/SuperApp/tmp' ``PlatformDirs`` for convenience ================================ @@ -171,6 +188,10 @@ '/Users/trentm/Library/Caches/SuperApp' >>> dirs.user_log_dir '/Users/trentm/Library/Logs/SuperApp' + >>> dirs.user_documents_dir + '/Users/trentm/Documents' + >>> dirs.user_runtime_dir + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp' Per-version isolation ===================== @@ -189,6 +210,10 @@ '/Users/trentm/Library/Caches/SuperApp/1.0' >>> dirs.user_log_dir '/Users/trentm/Library/Logs/SuperApp/1.0' + >>> dirs.user_documents_dir + '/Users/trentm/Documents' + >>> dirs.user_runtime_dir + '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0' Be wary of using this for configuration files though; you'll need to handle migrating configuration files manually. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/tests/conftest.py new/platformdirs-2.4.0/tests/conftest.py --- old/platformdirs-2.2.0/tests/conftest.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/tests/conftest.py 2021-09-25 22:45:42.000000000 +0200 @@ -9,6 +9,8 @@ "user_cache_dir", "user_state_dir", "user_log_dir", + "user_documents_dir", + "user_runtime_dir", "site_data_dir", "site_config_dir", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/tests/test_android.py new/platformdirs-2.4.0/tests/test_android.py --- old/platformdirs-2.2.0/tests/test_android.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/tests/test_android.py 2021-09-25 22:45:42.000000000 +0200 @@ -48,6 +48,8 @@ "user_cache_dir": f"/data/data/com.example/cache{suffix}", "user_state_dir": f"/data/data/com.example/files{suffix}", "user_log_dir": f"/data/data/com.example/cache{suffix}{'' if params.get('opinion', True) is False else '/log'}", + "user_documents_dir": "/storage/emulated/0/Documents", + "user_runtime_dir": f"/data/data/com.example/cache{suffix}{'' if not params.get('opinion', True) else '/tmp'}", } expected = expected_map[func] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/tests/test_api.py new/platformdirs-2.4.0/tests/test_api.py --- old/platformdirs-2.2.0/tests/test_api.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/tests/test_api.py 2021-09-25 22:45:42.000000000 +0200 @@ -16,7 +16,7 @@ def test_method_result_is_str(func: str) -> None: method = getattr(platformdirs, func) - result = method("MyApp", "MyCompany") + result = method() assert isinstance(result, str) @@ -28,7 +28,7 @@ def test_method_result_is_path(func_path: str) -> None: method = getattr(platformdirs, func_path) - result = method("MyApp", "MyCompany") + result = method() assert isinstance(result, Path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/tests/test_comp_with_appdirs.py new/platformdirs-2.4.0/tests/test_comp_with_appdirs.py --- old/platformdirs-2.2.0/tests/test_comp_with_appdirs.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/tests/test_comp_with_appdirs.py 2021-09-25 22:45:42.000000000 +0200 @@ -1,4 +1,5 @@ import sys +from inspect import getmembers, isfunction from typing import Any, Dict import appdirs @@ -13,6 +14,24 @@ assert AppDirs is platformdirs.PlatformDirs +def test_has_all_functions() -> None: + # Get all public function names from appdirs + appdirs_function_names = [f[0] for f in getmembers(appdirs, isfunction) if not f[0].startswith("_")] + + # Exception will be raised if any appdirs functions aren't in platformdirs. + for function_name in appdirs_function_names: + getattr(platformdirs, function_name) + + +def test_has_all_properties() -> None: + # Get names of all the properties of appdirs.AppDirs + appdirs_property_names = [p[0] for p in getmembers(appdirs.AppDirs, lambda member: isinstance(member, property))] + + # Exception will be raised if any appdirs.AppDirs properties aren't in platformdirs.AppDirs + for property_name in appdirs_property_names: + getattr(platformdirs.AppDirs, property_name) + + @pytest.mark.parametrize( "params", [ @@ -29,6 +48,10 @@ ], ) def test_compatibility(params: Dict[str, Any], func: str) -> None: + # Only test functions that are part of appdirs + if getattr(appdirs, func, None) is None: + pytest.skip(f"`{func}` does not exist in `appdirs`") + if sys.platform == "darwin": msg = { # pragma: no cover "user_log_dir": "without appname produces NoneType error", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/tests/test_unix.py new/platformdirs-2.4.0/tests/test_unix.py --- old/platformdirs-2.2.0/tests/test_unix.py 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/tests/test_unix.py 2021-09-25 22:45:42.000000000 +0200 @@ -1,18 +1,55 @@ +import importlib import os +import sys import typing import pytest from _pytest.monkeypatch import MonkeyPatch +from pytest_mock import MockerFixture from platformdirs.unix import Unix +def test_user_documents_dir(mocker: MockerFixture) -> None: + example_path = "/home/example/ExampleDocumentsFolder" + mock = mocker.patch("platformdirs.unix._get_user_dirs_folder") + mock.return_value = example_path + assert Unix().user_documents_dir == example_path + + +def test_user_documents_dir_env_var(mocker: MockerFixture) -> None: + # Mock documents dir not being in user-dirs.dirs file + mock = mocker.patch("platformdirs.unix._get_user_dirs_folder") + mock.return_value = None + + example_path = "/home/example/ExampleDocumentsFolder" + mocker.patch.dict(os.environ, {"XDG_DOCUMENTS_DIR": example_path}) + + assert Unix().user_documents_dir == example_path + + +def test_user_documents_dir_default(mocker: MockerFixture) -> None: + # Mock documents dir not being in user-dirs.dirs file + mock = mocker.patch("platformdirs.unix._get_user_dirs_folder") + mock.return_value = None + + # Mock no XDG_DOCUMENTS_DIR env variable being set + mocker.patch.dict(os.environ, {"XDG_DOCUMENTS_DIR": ""}) + + # Mock home directory + mocker.patch.dict(os.environ, {"HOME": "/home/example"}) + # Mock home directory for running the test on Windows + mocker.patch.dict(os.environ, {"USERPROFILE": "/home/example"}) + + assert Unix().user_documents_dir == "/home/example/Documents" + + class XDGVariable(typing.NamedTuple): name: str default_value: str -def _func_to_path(func: str) -> XDGVariable: +def _func_to_path(func: str) -> typing.Optional[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"), @@ -21,8 +58,9 @@ "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"), + "user_runtime_dir": XDGVariable("XDG_RUNTIME_DIR", "/run/user/1234"), } - return mapping[func] + return mapping.get(func) @pytest.fixture() @@ -30,22 +68,53 @@ return Unix(multipath=True, opinion=False) +@pytest.fixture() +def _getuid(mocker: MockerFixture) -> None: + mocker.patch("platformdirs.unix.getuid", return_value=1234) + + +@pytest.mark.usefixtures("_getuid") def test_xdg_variable_not_set(monkeypatch: MonkeyPatch, dirs_instance: Unix, func: str) -> None: xdg_variable = _func_to_path(func) + if xdg_variable is None: + return + monkeypatch.delenv(xdg_variable.name, raising=False) result = getattr(dirs_instance, func) assert result == os.path.expanduser(xdg_variable.default_value) +@pytest.mark.usefixtures("_getuid") def test_xdg_variable_empty_value(monkeypatch: MonkeyPatch, dirs_instance: Unix, func: str) -> None: xdg_variable = _func_to_path(func) + if xdg_variable is None: + return + monkeypatch.setenv(xdg_variable.name, "") result = getattr(dirs_instance, func) assert result == os.path.expanduser(xdg_variable.default_value) +@pytest.mark.usefixtures("_getuid") def test_xdg_variable_custom_value(monkeypatch: MonkeyPatch, dirs_instance: Unix, func: str) -> None: xdg_variable = _func_to_path(func) + if xdg_variable is None: + return + monkeypatch.setenv(xdg_variable.name, "/tmp/custom-dir") result = getattr(dirs_instance, func) assert result == "/tmp/custom-dir" + + +def test_platform_non_linux(monkeypatch: MonkeyPatch) -> None: + from platformdirs import unix + + try: + with monkeypatch.context() as context: + context.setattr(sys, "platform", "magic") + monkeypatch.delenv("XDG_RUNTIME_DIR", raising=False) + importlib.reload(unix) + with pytest.raises(RuntimeError, match="should only be used on Linux"): + unix.Unix().user_runtime_dir + finally: + importlib.reload(unix) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformdirs-2.2.0/whitelist.txt new/platformdirs-2.4.0/whitelist.txt --- old/platformdirs-2.2.0/whitelist.txt 2021-07-29 13:51:20.000000000 +0200 +++ new/platformdirs-2.4.0/whitelist.txt 2021-09-25 22:45:42.000000000 +0200 @@ -8,10 +8,12 @@ const csidl delenv -Dirs +dirs func +getmembers +getuid highbit -HKEY +hkey intersphinx isfunction jnius @@ -26,9 +28,11 @@ pathsep platformdirs pyjnius +runtime setenv shell32 typehints unittest +usefixtures winreg -XDG +xdg