Projects
Mega:24.09
python-platformdirs
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 2
View file
_service:tar_scm:python-platformdirs.spec
Changed
@@ -1,6 +1,6 @@ %global _empty_manifest_terminate_build 0 Name: python-platformdirs -Version: 3.11.0 +Version: 4.2.2 Release: 1 Summary: A small Python module for determining appropriate platform-specific dirs License: MIT @@ -69,6 +69,17 @@ %{_docdir}/* %changelog +* Fri Jun 28 2024 yaoxin <yao_xin001@hoperun.com> - 4.2.2-1 +- Update to 4.2.2 + * Fix android detection when python4android is present + * Switch to ruff for formatting and use codespell and docformatter + * Use hatch over tox by + * Allow working without ctypes by + * Fix 2 typos about XDG_DATA_DIR + * Add convenience methods to PlatformDirsAPI that allow iterating over both user and site dirs/paths. + * Drop support for EOL Python 3.7 + * site_cache_dir: Use /var/cache again instead of /var/tmp on UNIX + * Mon Jan 15 2024 xu_ping <707078654@qq.com> - 3.11.0-1 - Upgrade the version to 3.11.0
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="scm">git</param> <param name="url">git@gitee.com:src-openeuler/python-platformdirs.git</param> - <param name="revision">master</param> + <param name="revision">openEuler-24.09</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/tox.ini
Deleted
@@ -1,117 +0,0 @@ -tox -requires = - tox>=4.2 -env_list = - fix - py312 - py311 - py310 - py39 - py38 - py37 - pypy3 - type - coverage - readme - docs -skip_missing_interpreters = true - -testenv -description = run the unit tests with pytest under {basepython} -package = wheel -wheel_build_env = .pkg -extras = - test -pass_env = - ANDROID_DATA - ANDROID_ROOT -set_env = - COVERAGE_FILE = {toxworkdir}/.coverage.{envname} - COVERAGE_PROCESS_START = {toxinidir}/pyproject.toml - _COVERAGE_SRC = {envsitepackagesdir}/platformdirs -commands = - pytest {tty:--color=yes} {posargs: \ - --junitxml {toxworkdir}{/}junit.{envname}.xml --cov {envsitepackagesdir}{/}platformdirs \ - --cov {toxinidir}{/}tests \ - --cov-config=pyproject.toml --no-cov-on-fail --cov-report term-missing:skip-covered --cov-context=test \ - --cov-report html:{envtmpdir}{/}htmlcov --cov-report xml:{toxworkdir}{/}coverage.{envname}.xml \ - tests} - -testenv:fix -description = run static analysis and style check using flake8 -skip_install = true -deps = - pre-commit>=3.3.3 -pass_env = - HOMEPATH - PROGRAMDATA -commands = - pre-commit run --all-files --show-diff-on-failure - -testenv:type -description = run type check on code base -deps = - mypy==1.4.1 -set_env = - {tty:MYPY_FORCE_COLOR = 1} -commands = - mypy --strict src - mypy --strict tests - -testenv:coverage -description = combine coverage files and generate diff (against DIFF_AGAINST defaulting to origin/main) -skip_install = true -deps = - covdefaults>=2.3 - coveragetoml>=7.2.7 - diff-cover>=7.7 -extras = -parallel_show_output = true -pass_env = - DIFF_AGAINST -set_env = - COVERAGE_FILE = {toxworkdir}/.coverage -commands = - coverage combine - coverage report --skip-covered --show-missing - coverage xml -o {toxworkdir}/coverage.xml - coverage html -d {toxworkdir}/htmlcov - diff-cover --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml -depends = - py311 - py310 - py39 - py38 - py37 - pypy3 - -testenv:readme -description = check that the long description is valid -skip_install = true -deps = - buildvirtualenv>=0.10 - twine>=4.0.2 -pass_env = - * -change_dir = {toxinidir} -commands = - python -m build -o {envtmpdir} . - twine check {envtmpdir}/* - -testenv:docs -base_python = 3.10 -extras = - docs -commands = - python -c 'import glob; import subprocess; subprocess.call("proselint" + glob.glob("docs/*.rst"))' - sphinx-build -d "{envtmpdir}/doctree" docs "{toxworkdir}/docs_out" --color -b html {posargs} - python -c 'import pathlib; print("documentation available under \{0\}".format((pathlib.Path(r"{toxworkdir}") / "docs_out" / "index.html").as_uri()))' - -testenv:dev -description = generate a DEV environment -package = editable -extras = - test -commands = - python -m pip list --format=columns - python -c 'import sys; print(sys.executable)'
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/.gitignore -> _service:tar_scm:platformdirs-4.2.2.tar.gz/.gitignore
Changed
@@ -1,10 +1,7 @@ -/.idea/ -/.vscode/ - *.pyc *.egg-info -tmp/ -build/ -dist/ -.tox/ +/dist +/.tox /src/platformdirs/version.py +/report +/docs/build
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/PKG-INFO -> _service:tar_scm:platformdirs-4.2.2.tar.gz/PKG-INFO
Changed
@@ -1,7 +1,7 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.3 Name: platformdirs -Version: 3.11.0 -Summary: A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir". +Version: 4.2.2 +Summary: A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`. Project-URL: Documentation, https://platformdirs.readthedocs.io Project-URL: Homepage, https://github.com/platformdirs/platformdirs Project-URL: Source, https://github.com/platformdirs/platformdirs @@ -16,7 +16,6 @@ Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 @@ -25,19 +24,20 @@ Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules -Requires-Python: >=3.7 -Requires-Dist: typing-extensions>=4.7.1; python_version < '3.8' +Requires-Python: >=3.8 Provides-Extra: docs -Requires-Dist: furo>=2023.7.26; extra == 'docs' +Requires-Dist: furo>=2023.9.10; extra == 'docs' Requires-Dist: proselint>=0.13; extra == 'docs' -Requires-Dist: sphinx-autodoc-typehints>=1.24; extra == 'docs' -Requires-Dist: sphinx>=7.1.1; extra == 'docs' +Requires-Dist: sphinx-autodoc-typehints>=1.25.2; extra == 'docs' +Requires-Dist: sphinx>=7.2.6; extra == 'docs' Provides-Extra: test Requires-Dist: appdirs==1.4.4; extra == 'test' Requires-Dist: covdefaults>=2.3; extra == 'test' Requires-Dist: pytest-cov>=4.1; extra == 'test' -Requires-Dist: pytest-mock>=3.11.1; extra == 'test' -Requires-Dist: pytest>=7.4; extra == 'test' +Requires-Dist: pytest-mock>=3.12; extra == 'test' +Requires-Dist: pytest>=7.4.3; extra == 'test' +Provides-Extra: type +Requires-Dist: mypy>=1.8; extra == 'type' Description-Content-Type: text/x-rst The problem @@ -174,7 +174,7 @@ >>> user_cache_dir(appname, appauthor) '/home/trentm/.cache/SuperApp' >>> user_log_dir(appname, appauthor) - '/home/trentm/.cache/SuperApp/log' + '/home/trentm/.local/state/SuperApp/log' >>> user_config_dir(appname) '/home/trentm/.config/SuperApp' >>> user_documents_dir()
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/README.rst -> _service:tar_scm:platformdirs-4.2.2.tar.gz/README.rst
Changed
@@ -132,7 +132,7 @@ >>> user_cache_dir(appname, appauthor) '/home/trentm/.cache/SuperApp' >>> user_log_dir(appname, appauthor) - '/home/trentm/.cache/SuperApp/log' + '/home/trentm/.local/state/SuperApp/log' >>> user_config_dir(appname) '/home/trentm/.config/SuperApp' >>> user_documents_dir()
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/pyproject.toml -> _service:tar_scm:platformdirs-4.2.2.tar.gz/pyproject.toml
Changed
@@ -1,13 +1,13 @@ build-system build-backend = "hatchling.build" requires = - "hatch-vcs>=0.3", - "hatchling>=1.17.1", + "hatch-vcs>=0.4", + "hatchling>=1.18", project name = "platformdirs" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." readme = "README.rst" keywords = "appdirs", @@ -24,7 +24,7 @@ { name = "Ofek Lev", email = "oss@ofek.dev" }, { name = "Ronny Pfannschmidt", email = "opensource@ronnypfannschmidt.de" }, -requires-python = ">=3.7" +requires-python = ">=3.8" classifiers = "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", @@ -32,7 +32,6 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -45,21 +44,21 @@ dynamic = "version", -dependencies = - 'typing-extensions>=4.7.1; python_version < "3.8"', - optional-dependencies.docs = - "furo>=2023.7.26", + "furo>=2023.9.10", "proselint>=0.13", - "sphinx>=7.1.1", - "sphinx-autodoc-typehints>=1.24", + "sphinx>=7.2.6", + "sphinx-autodoc-typehints>=1.25.2", optional-dependencies.test = "appdirs==1.4.4", "covdefaults>=2.3", - "pytest>=7.4", + "pytest>=7.4.3", "pytest-cov>=4.1", - "pytest-mock>=3.11.1", + "pytest-mock>=3.12", + +optional-dependencies.type = + "mypy>=1.8", urls.Documentation = "https://platformdirs.readthedocs.io" urls.Homepage = "https://github.com/platformdirs/platformdirs" @@ -68,47 +67,197 @@ tool.hatch build.hooks.vcs.version-file = "src/platformdirs/version.py" -build.targets.sdist.include = "/src", "/tests", "/tox.ini" +build.targets.sdist.include = + "/src", + "/tests", + "/tox.ini", + version.source = "vcs" -tool.black -line-length = 120 +tool.hatch.envs.default +description = "Development environment" +features = + "test", + "docs", + "type", + +scripts = { show = + "python -m pip list --format=columns", + 'python -c "import sys; print(sys.executable)"', + } + +tool.hatch.envs.test +template = "test" +# dev-mode = false # cannot enable this until https://github.com/pypa/hatch/issues/1237 +description = "Run the test suite" +matrix = + { python = + "3.12", + "3.11", + "3.10", + "3.9", + "3.8", + "pypy3.9", + }, + +features = + "test", + +env-vars = { COVERAGE_FILE = "report/.coverage.{matrix:python}", COVERAGE_PROCESS_START = "pyproject.toml", _COVERAGE_SRC = "src/platformdirs" } +tool.hatch.envs.test.scripts +run = + """ + pytest --junitxml report/junit.{matrix:python}.xml --cov src/platformdirs --cov tests \ + --cov-config=pyproject.toml --no-cov-on-fail --cov-report term-missing:skip-covered --cov-context=test \ + --cov-report html:report/html{matrix:python} --cov-report xml:report/coverage{matrix:python}.xml \ + tests +""", + + +tool.hatch.envs.coverage +template = "coverage" +description = "combine coverage files and generate diff" +dependencies = + "covdefaults>=2.3", + "coveragetoml>=7.3.2", + "diff-cover>=8.0.1", + +env-vars = { COVERAGE_FILE = "report/.coverage" } +tool.hatch.envs.coverage.scripts +run = + "coverage combine report", + "coverage report --skip-covered --show-missing", + "coverage xml -o report/coverage.xml", + "coverage html -d report/html", + "diff-cover --compare-branch {env:DIFF_AGAINST:origin/main} report/coverage.xml", + + +tool.hatch.envs.type +template = "type" +description = "Run the type checker" +python = "3.12" +dev-mode = false +features = + "type", + "test", + +scripts = { run = + "mypy --strict src", + "mypy --strict tests", + } + +tool.hatch.envs.fix +template = "fix" +description = "Run the pre-commit tool to lint and autofix issues" +python = "3.12" +detached = true +dependencies = + "pre-commit>=3.6", + +scripts = { "run" = + "pre-commit run --all-files --show-diff-on-failure", + } + +tool.hatch.envs.docs +template = "docs" +description = "Build documentation using Sphinx" +python = "3.12" +dev-mode = false +features = + "docs", + +tool.hatch.envs.docs.scripts +build = + """python -c "import glob; import subprocess; subprocess.call('proselint' + glob.glob('docs/*.rst'))" """, + """python -c "from shutil import rmtree; rmtree('docs/build', ignore_errors=True)" """, + "sphinx-build -d docs/build/tree docs docs/build --color -b html", + """python -c "from pathlib import Path; p=(Path('docs')/'build'/'index.html').absolute().as_uri(); print('Documentation built under '+p)" """, + + +tool.hatch.envs.readme +template = "readme" +description = "check that the long description is valid" +python = "3.12" +dependencies = + "buildvirtualenv>=1.0.3", + "twine>=4.0.2", + "check-wheel-contents>=0.6.0", + +scripts = { "run" = + "python -m build -o dist", + "twine check dist/*.whl dist/*.tar.gz", + "check-wheel-contents dist", + } tool.ruff -select = "ALL" +select = + "ALL", + line-length = 120 -target-version = "py37"
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/__init__.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/__init__.py
Changed
@@ -1,7 +1,10 @@ """ -Utilities for determining application-specific dirs. See <https://github.com/platformdirs/platformdirs> for details and -usage. +Utilities for determining application-specific dirs. + +See <https://github.com/platformdirs/platformdirs> for details and usage. + """ + from __future__ import annotations import os @@ -14,31 +17,27 @@ if TYPE_CHECKING: from pathlib import Path - - if sys.version_info >= (3, 8): # pragma: no cover (py38+) - from typing import Literal - else: # pragma: no cover (py38+) - from typing_extensions import Literal + from typing import Literal def _set_platform_dir_class() -> typePlatformDirsABC: if sys.platform == "win32": - from platformdirs.windows import Windows as Result + from platformdirs.windows import Windows as Result # noqa: PLC0415 elif sys.platform == "darwin": - from platformdirs.macos import MacOS as Result + from platformdirs.macos import MacOS as Result # noqa: PLC0415 else: - from platformdirs.unix import Unix as Result + from platformdirs.unix import Unix as Result # noqa: PLC0415 if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system": if os.getenv("SHELL") or os.getenv("PREFIX"): return Result - from platformdirs.android import _android_folder + from platformdirs.android import _android_folder # noqa: PLC0415 if _android_folder() is not None: - from platformdirs.android import Android + from platformdirs.android import Android # noqa: PLC0415 - return Android # return to avoid redefinition of result + return Android # return to avoid redefinition of a result return Result @@ -510,7 +509,7 @@ def user_documents_path() -> Path: - """:returns: documents path tied to the user""" + """:returns: documents a path tied to the user""" return PlatformDirs().user_documents_path @@ -588,41 +587,41 @@ __all__ = - "__version__", - "__version_info__", - "PlatformDirs", "AppDirs", + "PlatformDirs", "PlatformDirsABC", - "user_data_dir", - "user_config_dir", - "user_cache_dir", - "user_state_dir", - "user_log_dir", - "user_documents_dir", - "user_downloads_dir", - "user_pictures_dir", - "user_videos_dir", - "user_music_dir", - "user_desktop_dir", - "user_runtime_dir", - "site_data_dir", - "site_config_dir", + "__version__", + "__version_info__", "site_cache_dir", + "site_cache_path", + "site_config_dir", + "site_config_path", + "site_data_dir", + "site_data_path", "site_runtime_dir", - "user_data_path", - "user_config_path", + "site_runtime_path", + "user_cache_dir", "user_cache_path", - "user_state_path", - "user_log_path", + "user_config_dir", + "user_config_path", + "user_data_dir", + "user_data_path", + "user_desktop_dir", + "user_desktop_path", + "user_documents_dir", "user_documents_path", + "user_downloads_dir", "user_downloads_path", - "user_pictures_path", - "user_videos_path", + "user_log_dir", + "user_log_path", + "user_music_dir", "user_music_path", - "user_desktop_path", + "user_pictures_dir", + "user_pictures_path", + "user_runtime_dir", "user_runtime_path", - "site_data_path", - "site_config_path", - "site_cache_path", - "site_runtime_path", + "user_state_dir", + "user_state_path", + "user_videos_dir", + "user_videos_path",
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/__main__.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/__main__.py
Changed
@@ -1,4 +1,5 @@ """Main entry point.""" + from __future__ import annotations from platformdirs import PlatformDirs, __version__ @@ -23,7 +24,7 @@ def main() -> None: - """Run main entry point.""" + """Run the main entry point.""" app_name = "MyApp" app_author = "MyCompany"
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/android.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/android.py
Changed
@@ -1,21 +1,23 @@ """Android.""" + from __future__ import annotations import os import re import sys from functools import lru_cache -from typing import cast +from typing import TYPE_CHECKING, cast from .api import PlatformDirsABC class Android(PlatformDirsABC): """ - Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_. Makes use of the - `appname <platformdirs.api.PlatformDirsABC.appname>`, - `version <platformdirs.api.PlatformDirsABC.version>`, - `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`. + Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_. + + Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `version + <platformdirs.api.PlatformDirsABC.version>`, `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`. + """ @property @@ -43,7 +45,7 @@ @property def user_cache_dir(self) -> str: - """:return: cache directory tied to the user, e.g. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>``""" + """:return: cache directory tied to the user, e.g.,``/data/user/<userid>/<packagename>/cache/<AppName>``""" return self._append_app_name_and_version(cast(str, _android_folder()), "cache") @property @@ -115,16 +117,33 @@ @lru_cache(maxsize=1) -def _android_folder() -> str | None: +def _android_folder() -> str | None: # noqa: C901, PLR0912 """:return: base folder for the Android OS or None if it cannot be found""" - try: - # First try to get path to android app via pyjnius - from jnius import autoclass - - context = autoclass("android.content.Context") - result: str | None = context.getFilesDir().getParentFile().getAbsolutePath() - except Exception: # noqa: BLE001 - # if fails find an android folder looking path on the sys.path + result: str | None = None + # type checker isn't happy with our "import android", just don't do this when type checking see + # https://stackoverflow.com/a/61394121 + if not TYPE_CHECKING: + try: + # First try to get a path to android app using python4android (if available)... + from android import mActivity # noqa: PLC0415 + + context = cast("android.content.Context", mActivity.getApplicationContext()) # noqa: F821 + result = context.getFilesDir().getParentFile().getAbsolutePath() + except Exception: # noqa: BLE001 + result = None + if result is None: + try: + # ...and fall back to using plain pyjnius, if python4android isn't available or doesn't deliver any useful + # result... + from jnius import autoclass # noqa: PLC0415 + + context = autoclass("android.content.Context") + result = context.getFilesDir().getParentFile().getAbsolutePath() + except Exception: # noqa: BLE001 + result = None + if result is None: + # and if that fails, too, find an android folder looking at path on the sys.path + # warning: only works for apps installed under /data, not adopted storage etc. pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files") for path in sys.path: if pattern.match(path): @@ -132,6 +151,16 @@ break else: result = None + if result is None: + # one last try: find an android folder looking at path on the sys.path taking adopted storage paths into + # account + pattern = re.compile(r"/mnt/expand/a-fA-F0-9-{36}/(data|user/\d+)/(.+)/files") + for path in sys.path: + if pattern.match(path): + result = path.split("/files")0 + break + else: + result = None return result @@ -140,7 +169,7 @@ """:return: documents folder for the Android OS""" # Get directories with pyjnius try: - from jnius import autoclass + from jnius import autoclass # noqa: PLC0415 context = autoclass("android.content.Context") environment = autoclass("android.os.Environment") @@ -156,7 +185,7 @@ """:return: downloads folder for the Android OS""" # Get directories with pyjnius try: - from jnius import autoclass + from jnius import autoclass # noqa: PLC0415 context = autoclass("android.content.Context") environment = autoclass("android.os.Environment") @@ -172,7 +201,7 @@ """:return: pictures folder for the Android OS""" # Get directories with pyjnius try: - from jnius import autoclass + from jnius import autoclass # noqa: PLC0415 context = autoclass("android.content.Context") environment = autoclass("android.os.Environment") @@ -188,7 +217,7 @@ """:return: videos folder for the Android OS""" # Get directories with pyjnius try: - from jnius import autoclass + from jnius import autoclass # noqa: PLC0415 context = autoclass("android.content.Context") environment = autoclass("android.os.Environment") @@ -204,7 +233,7 @@ """:return: music folder for the Android OS""" # Get directories with pyjnius try: - from jnius import autoclass + from jnius import autoclass # noqa: PLC0415 context = autoclass("android.content.Context") environment = autoclass("android.os.Environment")
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/api.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/api.py
Changed
@@ -1,4 +1,5 @@ """Base API.""" + from __future__ import annotations import os @@ -7,18 +8,13 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - import sys - - if sys.version_info >= (3, 8): # pragma: no cover (py38+) - from typing import Literal - else: # pragma: no cover (py38+) - from typing_extensions import Literal + from typing import Iterator, Literal -class PlatformDirsABC(ABC): +class PlatformDirsABC(ABC): # noqa: PLR0904 """Abstract base class for platform directories.""" - def __init__( # noqa: PLR0913 + def __init__( # noqa: PLR0913, PLR0917 self, appname: str | None = None, appauthor: str | None | LiteralFalse = None, @@ -38,34 +34,47 @@ :param multipath: See `multipath`. :param opinion: See `opinion`. :param ensure_exists: See `ensure_exists`. + """ self.appname = appname #: The name of application. self.appauthor = appauthor """ - The name of the app author or distributing body for this application. Typically, it is the owning company name. - Defaults to `appname`. You may pass ``False`` to disable it. + The name of the app author or distributing body for this application. + + Typically, it is the owning company name. Defaults to `appname`. You may pass ``False`` to disable it. + """ self.version = version """ - An optional version path element to append to the path. You might want to use this if you want multiple versions - of your app to be able to run independently. If used, this would typically be ``<major>.<minor>``. + An optional version path element to append to the path. + + You might want to use this if you want multiple versions of your app to be able to run independently. If used, + this would typically be ``<major>.<minor>``. + """ self.roaming = roaming """ - Whether to use the roaming appdata directory on Windows. That means that for users on a Windows network setup - for roaming profiles, this user data will be synced on login (see - `here <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>`_). + Whether to use the roaming appdata directory on Windows. + + That means that for users on a Windows network setup for roaming profiles, this user data will be synced on + login (see + `here <https://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>`_). + """ self.multipath = multipath """ An optional parameter which indicates that the entire list of data dirs should be returned. + By default, the first item would only be returned. + """ self.opinion = opinion #: A flag to indicating to use opinionated values. self.ensure_exists = ensure_exists """ Optionally create the directory (and any missing parents) upon access if it does not exist. + By default, no directories are created. + """ def _append_app_name_and_version(self, *base: str) -> str: @@ -204,7 +213,7 @@ @property def user_documents_path(self) -> Path: - """:return: documents path tied to the user""" + """:return: documents a path tied to the user""" return Path(self.user_documents_dir) @property @@ -241,3 +250,43 @@ def site_runtime_path(self) -> Path: """:return: runtime path shared by users""" return Path(self.site_runtime_dir) + + def iter_config_dirs(self) -> Iteratorstr: + """:yield: all user and site configuration directories.""" + yield self.user_config_dir + yield self.site_config_dir + + def iter_data_dirs(self) -> Iteratorstr: + """:yield: all user and site data directories.""" + yield self.user_data_dir + yield self.site_data_dir + + def iter_cache_dirs(self) -> Iteratorstr: + """:yield: all user and site cache directories.""" + yield self.user_cache_dir + yield self.site_cache_dir + + def iter_runtime_dirs(self) -> Iteratorstr: + """:yield: all user and site runtime directories.""" + yield self.user_runtime_dir + yield self.site_runtime_dir + + def iter_config_paths(self) -> IteratorPath: + """:yield: all user and site configuration paths.""" + for path in self.iter_config_dirs(): + yield Path(path) + + def iter_data_paths(self) -> IteratorPath: + """:yield: all user and site data paths.""" + for path in self.iter_data_dirs(): + yield Path(path) + + def iter_cache_paths(self) -> IteratorPath: + """:yield: all user and site cache paths.""" + for path in self.iter_cache_dirs(): + yield Path(path) + + def iter_runtime_paths(self) -> IteratorPath: + """:yield: all user and site runtime paths.""" + for path in self.iter_runtime_dirs(): + yield Path(path)
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/macos.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/macos.py
Changed
@@ -1,4 +1,5 @@ """macOS.""" + from __future__ import annotations import os.path @@ -9,11 +10,14 @@ class MacOS(PlatformDirsABC): """ - Platform directories for the macOS operating system. Follows the guidance from `Apple documentation - <https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html>`_. + Platform directories for the macOS operating system. + + Follows the guidance from + `Apple documentation <https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html>`_. Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `version <platformdirs.api.PlatformDirsABC.version>`, `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`. + """ @property @@ -27,7 +31,7 @@ :return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``. If we're using a Python binary managed by `Homebrew <https://brew.sh>`_, the directory will be under the Homebrew prefix, e.g. ``/opt/homebrew/share/$appname/$version``. - If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled and we're in Homebrew, + If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled, and we're in Homebrew, the response is a multi-path string separated by ":", e.g. ``/opt/homebrew/share/$appname/$version:/Library/Application Support/$appname/$version`` """ @@ -59,7 +63,7 @@ :return: cache directory shared by users, e.g. ``/Library/Caches/$appname/$version``. If we're using a Python binary managed by `Homebrew <https://brew.sh>`_, the directory will be under the Homebrew prefix, e.g. ``/opt/homebrew/var/cache/$appname/$version``. - If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled and we're in Homebrew, + If `multipath <platformdirs.api.PlatformDirsABC.multipath>` is enabled, and we're in Homebrew, the response is a multi-path string separated by ":", e.g. ``/opt/homebrew/var/cache/$appname/$version:/Library/Caches/$appname/$version`` """
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/unix.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/unix.py
Changed
@@ -1,16 +1,18 @@ """Unix.""" + from __future__ import annotations import os import sys from configparser import ConfigParser from pathlib import Path +from typing import Iterator, NoReturn from .api import PlatformDirsABC if sys.platform == "win32": - def getuid() -> int: + def getuid() -> NoReturn: msg = "should only be used on Unix" raise RuntimeError(msg) @@ -18,17 +20,17 @@ from os import getuid -class Unix(PlatformDirsABC): +class Unix(PlatformDirsABC): # noqa: PLR0904 """ - On Unix/Linux, we follow the - `XDG Basedir Spec <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_. The spec allows - overriding directories with environment variables. The examples show are the default values, alongside the name of - the environment variable that overrides them. Makes use of the - `appname <platformdirs.api.PlatformDirsABC.appname>`, - `version <platformdirs.api.PlatformDirsABC.version>`, - `multipath <platformdirs.api.PlatformDirsABC.multipath>`, - `opinion <platformdirs.api.PlatformDirsABC.opinion>`, - `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`. + On Unix/Linux, we follow the `XDG Basedir Spec <https://specifications.freedesktop.org/basedir-spec/basedir-spec- + latest.html>`_. + + The spec allows overriding directories with environment variables. The examples shown are the default values, + alongside the name of the environment variable that overrides them. Makes use of the `appname + <platformdirs.api.PlatformDirsABC.appname>`, `version <platformdirs.api.PlatformDirsABC.version>`, `multipath + <platformdirs.api.PlatformDirsABC.multipath>`, `opinion <platformdirs.api.PlatformDirsABC.opinion>`, `ensure_exists + <platformdirs.api.PlatformDirsABC.ensure_exists>`. + """ @property @@ -43,24 +45,24 @@ return self._append_app_name_and_version(path) @property + def _site_data_dirs(self) -> liststr: + path = os.environ.get("XDG_DATA_DIRS", "") + if not path.strip(): + path = f"/usr/local/share{os.pathsep}/usr/share" + return self._append_app_name_and_version(p) for p in path.split(os.pathsep) + + @property def site_data_dir(self) -> str: """ :return: data directories shared by users (if `multipath <platformdirs.api.PlatformDirsABC.multipath>` is - enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS - path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version`` + enabled and ``XDG_DATA_DIRS`` is set and a multi path the response is also a multi path separated by the + OS path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version`` """ # XDG default for $XDG_DATA_DIRS; only first, if multipath is False - path = os.environ.get("XDG_DATA_DIRS", "") - if not path.strip(): - path = f"/usr/local/share{os.pathsep}/usr/share" - return self._with_multi_path(path) - - def _with_multi_path(self, path: str) -> str: - path_list = path.split(os.pathsep) + dirs = self._site_data_dirs if not self.multipath: - path_list = path_list0:1 - path_list = self._append_app_name_and_version(os.path.expanduser(p)) for p in path_list # noqa: PTH111 - return os.pathsep.join(path_list) + return dirs0 + return os.pathsep.join(dirs) @property def user_config_dir(self) -> str: @@ -74,17 +76,24 @@ return self._append_app_name_and_version(path) @property + def _site_config_dirs(self) -> liststr: + path = os.environ.get("XDG_CONFIG_DIRS", "") + if not path.strip(): + path = "/etc/xdg" + return self._append_app_name_and_version(p) for p in path.split(os.pathsep) + + @property def site_config_dir(self) -> str: """ :return: config directories shared by users (if `multipath <platformdirs.api.PlatformDirsABC.multipath>` - is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS - path separator), e.g. ``/etc/xdg/$appname/$version`` + is enabled and ``XDG_CONFIG_DIRS`` is set and a multi path the response is also a multi path separated by + the OS path separator), e.g. ``/etc/xdg/$appname/$version`` """ # XDG default for $XDG_CONFIG_DIRS only first, if multipath is False - path = os.environ.get("XDG_CONFIG_DIRS", "") - if not path.strip(): - path = "/etc/xdg" - return self._with_multi_path(path) + dirs = self._site_config_dirs + if not self.multipath: + return dirs0 + return os.pathsep.join(dirs) @property def user_cache_dir(self) -> str: @@ -99,8 +108,8 @@ @property def site_cache_dir(self) -> str: - """:return: cache directory shared by users, e.g. ``/var/tmp/$appname/$version``""" - return self._append_app_name_and_version("/var/tmp") # noqa: S108 + """:return: cache directory shared by users, e.g. ``/var/cache/$appname/$version``""" + return self._append_app_name_and_version("/var/cache") @property def user_state_dir(self) -> str: @@ -196,17 +205,17 @@ @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: data path shared by users. Only return the first item, even if ``multipath`` is set to ``True``""" return self._first_item_as_path_if_multipath(self.site_data_dir) @property def site_config_path(self) -> Path: - """:return: config path shared by the users. Only return first item, even if ``multipath`` is set to ``True``""" + """:return: config path shared by the users, returns the first item, even if ``multipath`` is set to ``True``""" return self._first_item_as_path_if_multipath(self.site_config_dir) @property def site_cache_path(self) -> Path: - """:return: cache path shared by users. Only return first item, even if ``multipath`` is set to ``True``""" + """:return: cache path shared by users. Only return the first item, even if ``multipath`` is set to ``True``""" return self._first_item_as_path_if_multipath(self.site_cache_dir) def _first_item_as_path_if_multipath(self, directory: str) -> Path: @@ -215,6 +224,16 @@ directory = directory.split(os.pathsep)0 return Path(directory) + def iter_config_dirs(self) -> Iteratorstr: + """:yield: all user and site configuration directories.""" + yield self.user_config_dir + yield from self._site_config_dirs + + def iter_data_dirs(self) -> Iteratorstr: + """:yield: all user and site data directories.""" + yield self.user_data_dir + yield from self._site_data_dirs + def _get_user_media_dir(env_var: str, fallback_tilde_path: str) -> str: media_dir = _get_user_dirs_folder(env_var) @@ -227,7 +246,12 @@ def _get_user_dirs_folder(key: str) -> str | None: - """Return directory from user-dirs.dirs config file. See https://freedesktop.org/wiki/Software/xdg-user-dirs/.""" + """ + Return directory from user-dirs.dirs config file. + + See https://freedesktop.org/wiki/Software/xdg-user-dirs/. + + """ user_dirs_config_path = Path(Unix().user_config_dir) / "user-dirs.dirs" if user_dirs_config_path.exists(): parser = ConfigParser()
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/version.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/version.py
Changed
@@ -12,5 +12,5 @@ __version_tuple__: VERSION_TUPLE version_tuple: VERSION_TUPLE -__version__ = version = '3.11.0' -__version_tuple__ = version_tuple = (3, 11, 0) +__version__ = version = '4.2.2' +__version_tuple__ = version_tuple = (4, 2, 2)
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/src/platformdirs/windows.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/src/platformdirs/windows.py
Changed
@@ -1,7 +1,7 @@ """Windows.""" + from __future__ import annotations -import ctypes import os import sys from functools import lru_cache @@ -15,15 +15,13 @@ class Windows(PlatformDirsABC): """ - `MSDN on where to store app data files - <http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120>`_. - Makes use of the - `appname <platformdirs.api.PlatformDirsABC.appname>`, - `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`, - `version <platformdirs.api.PlatformDirsABC.version>`, - `roaming <platformdirs.api.PlatformDirsABC.roaming>`, - `opinion <platformdirs.api.PlatformDirsABC.opinion>`, - `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`. + `MSDN on where to store app data files <https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid>`_. + + Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `appauthor + <platformdirs.api.PlatformDirsABC.appauthor>`, `version <platformdirs.api.PlatformDirsABC.version>`, `roaming + <platformdirs.api.PlatformDirsABC.roaming>`, `opinion <platformdirs.api.PlatformDirsABC.opinion>`, `ensure_exists + <platformdirs.api.PlatformDirsABC.ensure_exists>`. + """ @property @@ -164,7 +162,7 @@ def get_win_folder_if_csidl_name_not_env_var(csidl_name: str) -> str | None: - """Get folder for a CSIDL name that does not exist as an environment variable.""" + """Get a folder for a CSIDL name that does not exist as an environment variable.""" if csidl_name == "CSIDL_PERSONAL": return os.path.join(os.path.normpath(os.environ"USERPROFILE"), "Documents") # noqa: PTH118 @@ -188,6 +186,7 @@ This is a fallback technique at best. I'm not sure if using the registry for these guarantees us the correct answer for all CSIDL_* names. + """ shell_folder_name = { "CSIDL_APPDATA": "AppData", @@ -204,7 +203,7 @@ raise ValueError(msg) if sys.platform != "win32": # only needed for mypy type checker to know that this code runs only on Windows raise NotImplementedError - import winreg + import winreg # noqa: PLC0415 key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") directory, _ = winreg.QueryValueEx(key, shell_folder_name) @@ -217,6 +216,8 @@ # Use 'CSIDL_PROFILE' (40) and append the default folder 'Downloads' instead. # https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid + import ctypes # noqa: PLC0415 + csidl_const = { "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, @@ -249,10 +250,15 @@ def _pick_get_win_folder() -> Callablestr, str: - if hasattr(ctypes, "windll"): - return get_win_folder_via_ctypes try: - import winreg # noqa: F401 + import ctypes # noqa: PLC0415 + except ImportError: + pass + else: + if hasattr(ctypes, "windll"): + return get_win_folder_via_ctypes + try: + import winreg # noqa: PLC0415, F401 except ImportError: return get_win_folder_from_env_vars else:
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/tests/test_android.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/tests/test_android.py
Changed
@@ -67,14 +67,17 @@ assert result == expected -def test_android_folder_from_jnius(mocker: MockerFixture) -> None: - from platformdirs import PlatformDirs - from platformdirs.android import _android_folder +def test_android_folder_from_jnius(mocker: MockerFixture, monkeypatch: pytest.MonkeyPatch) -> None: + from platformdirs import PlatformDirs # noqa: PLC0415 + from platformdirs.android import _android_folder # noqa: PLC0415 + + mocker.patch.dict(sys.modules, {"android": MagicMock(side_effect=ModuleNotFoundError)}) + monkeypatch.delitem(__import__("sys").modules, "android") _android_folder.cache_clear() if PlatformDirs is Android: - import jnius # pragma: no cover + import jnius # pragma: no cover # noqa: PLC0415 autoclass = mocker.spy(jnius, "autoclass") # pragma: no cover else: @@ -93,17 +96,44 @@ assert autoclass.call_count == 1 +def test_android_folder_from_p4a(mocker: MockerFixture, monkeypatch: pytest.MonkeyPatch) -> None: + from platformdirs.android import _android_folder # noqa: PLC0415 + + mocker.patch.dict(sys.modules, {"jnius": MagicMock(side_effect=ModuleNotFoundError)}) + monkeypatch.delitem(__import__("sys").modules, "jnius") + + _android_folder.cache_clear() + + get_absolute_path = MagicMock(return_value="/A") + get_parent_file = MagicMock(getAbsolutePath=get_absolute_path) + get_files_dir = MagicMock(getParentFile=MagicMock(return_value=get_parent_file)) + get_application_context = MagicMock(getFilesDir=MagicMock(return_value=get_files_dir)) + m_activity = MagicMock(getApplicationContext=MagicMock(return_value=get_application_context)) + mocker.patch.dict(sys.modules, {"android": MagicMock(mActivity=m_activity)}) + + result = _android_folder() + assert result == "/A" + assert get_absolute_path.call_count == 1 + + assert _android_folder() is result + assert get_absolute_path.call_count == 1 + + @pytest.mark.parametrize( "path", "/data/user/1/a/files", "/data/data/a/files", + "/mnt/expand/8e06fc2f-a86a-44e8-81ce-109e0eedd5ed/user/1/a/files", , ) def test_android_folder_from_sys_path(mocker: MockerFixture, path: str, monkeypatch: pytest.MonkeyPatch) -> None: - mocker.patch.dict(sys.modules, {"jnius": MagicMock(autoclass=MagicMock(side_effect=ModuleNotFoundError))}) + mocker.patch.dict(sys.modules, {"jnius": MagicMock(side_effect=ModuleNotFoundError)}) + monkeypatch.delitem(__import__("sys").modules, "jnius") + mocker.patch.dict(sys.modules, {"android": MagicMock(side_effect=ModuleNotFoundError)}) + monkeypatch.delitem(__import__("sys").modules, "android") - from platformdirs.android import _android_folder + from platformdirs.android import _android_folder # noqa: PLC0415 _android_folder.cache_clear() monkeypatch.setattr(sys, "path", "/A", "/B", path) @@ -115,7 +145,7 @@ def test_android_folder_not_found(mocker: MockerFixture, monkeypatch: pytest.MonkeyPatch) -> None: mocker.patch.dict(sys.modules, {"jnius": MagicMock(autoclass=MagicMock(side_effect=ModuleNotFoundError))}) - from platformdirs.android import _android_folder + from platformdirs.android import _android_folder # noqa: PLC0415 _android_folder.cache_clear() monkeypatch.setattr(sys, "path", )
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/tests/test_api.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/tests/test_api.py
Changed
@@ -1,14 +1,23 @@ from __future__ import annotations +import builtins +import functools import inspect import sys from pathlib import Path +from typing import TYPE_CHECKING, Any, Callable import pytest import platformdirs from platformdirs.android import Android +builtin_import = builtins.__import__ + + +if TYPE_CHECKING: + from types import ModuleType + def test_package_metadata() -> None: assert hasattr(platformdirs, "__version__") @@ -68,7 +77,7 @@ else: monkeypatch.setenv(env_var, value) - from platformdirs.android import _android_folder + from platformdirs.android import _android_folder # noqa: PLC0415 _android_folder.cache_clear() monkeypatch.setattr(sys, "path", "/A", "/B", path) @@ -80,3 +89,35 @@ assert platformdirs._set_platform_dir_class() is Android # noqa: SLF001 else: assert platformdirs._set_platform_dir_class() is not Android # noqa: SLF001 + + +def _fake_import(name: str, *args: Any, **kwargs: Any) -> ModuleType: # noqa: ANN401 + if name == "ctypes": + msg = f"No module named {name}" + raise ModuleNotFoundError(msg) + return builtin_import(name, *args, **kwargs) + + +def mock_import(func: Callable, None) -> Callable, None: + @functools.wraps(func) + def wrap() -> None: + platformdirs_module_items = item for item in sys.modules.items() if item0.startswith("platformdirs") + try: + builtins.__import__ = _fake_import + for name, _ in platformdirs_module_items: + del sys.modulesname + return func() + finally: + # restore original modules + builtins.__import__ = builtin_import + for name, module in platformdirs_module_items: + sys.modulesname = module + + return wrap + + +@mock_import +def test_no_ctypes() -> None: + import platformdirs # noqa: PLC0415 + + assert platformdirs
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/tests/test_comp_with_appdirs.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/tests/test_comp_with_appdirs.py
Changed
@@ -11,7 +11,7 @@ def test_has_backward_compatible_class() -> None: - from platformdirs import AppDirs + from platformdirs import AppDirs # noqa: PLC0415 assert AppDirs is platformdirs.PlatformDirs
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/tests/test_macos.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/tests/test_macos.py
Changed
@@ -15,9 +15,7 @@ @pytest.fixture(autouse=True) def _fix_os_pathsep(mocker: MockerFixture) -> None: - """ - If we're not actually running on macOS, set `os.pathsep` to what it should be on macOS. - """ + """If we're not running on macOS, set `os.pathsep` to what it should be on macOS.""" if sys.platform != "darwin": # pragma: darwin no cover mocker.patch("os.pathsep", ":") mocker.patch("os.path.pathsep", ":")
View file
_service:tar_scm:platformdirs-3.11.0.tar.gz/tests/test_main.py -> _service:tar_scm:platformdirs-4.2.2.tar.gz/tests/test_main.py
Changed
@@ -1,7 +1,7 @@ from __future__ import annotations import sys -from subprocess import check_output +from subprocess import check_output # noqa: S404 from platformdirs import __version__ from platformdirs.__main__ import PROPS
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2