././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0077024 jaraco_packaging-10.4.0/0000755000175100017510000000000015146630574014520 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/.coveragerc0000644000175100017510000000054515146630546016644 0ustar00runnerrunner[run] omit = # leading `*/` for pytest-dev/pytest-cov#456 */.tox/* disable_warnings = couldnt-parse [report] show_missing = True exclude_also = # Exclude common false positives per # https://coverage.readthedocs.io/en/latest/excluding.html#advanced-exclusion # Ref jaraco/skeleton#97 and jaraco/skeleton#135 class .*\bProtocol\): if TYPE_CHECKING: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/.editorconfig0000644000175100017510000000036615146630546017201 0ustar00runnerrunnerroot = true [*] charset = utf-8 indent_style = tab indent_size = 4 insert_final_newline = true end_of_line = lf [*.py] indent_style = space max_line_length = 88 [*.{yml,yaml}] indent_style = space indent_size = 2 [*.rst] indent_style = space ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1771778428.000703 jaraco_packaging-10.4.0/.github/0000755000175100017510000000000015146630574016060 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0037026 jaraco_packaging-10.4.0/.github/workflows/0000755000175100017510000000000015146630574020115 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/.github/workflows/main.yml0000644000175100017510000000631315146630546021566 0ustar00runnerrunnername: tests on: merge_group: push: branches-ignore: # temporary GH branches relating to merge queues (jaraco/skeleton#93) - gh-readonly-queue/** tags: # required if branches-ignore is supplied (jaraco/skeleton#103) - '**' pull_request: workflow_dispatch: permissions: contents: read env: # Environment variable to support color support (jaraco/skeleton#66) FORCE_COLOR: 1 # Suppress noisy pip warnings PIP_DISABLE_PIP_VERSION_CHECK: 'true' PIP_NO_WARN_SCRIPT_LOCATION: 'true' # Ensure tests can sense settings about the environment TOX_OVERRIDE: >- testenv.pass_env+=GITHUB_*,FORCE_COLOR jobs: test: strategy: # https://blog.jaraco.com/efficient-use-of-ci-resources/ matrix: python: - "3.9" - "3.13" platform: - ubuntu-latest - macos-latest - windows-latest include: - python: "3.10" platform: ubuntu-latest - python: "3.11" platform: ubuntu-latest - python: "3.12" platform: ubuntu-latest - python: "3.14" platform: ubuntu-latest - python: pypy3.10 platform: ubuntu-latest runs-on: ${{ matrix.platform }} continue-on-error: ${{ matrix.python == '3.14' }} steps: - uses: actions/checkout@v4 - name: Install build dependencies # Install dependencies for building packages on pre-release Pythons # jaraco/skeleton#161 if: matrix.python == '3.14' && matrix.platform == 'ubuntu-latest' run: | sudo apt update sudo apt install -y libxml2-dev libxslt-dev - name: Setup Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} allow-prereleases: true - name: Install tox run: python -m pip install tox - name: Run run: tox collateral: strategy: fail-fast: false matrix: job: - diffcov - docs runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.x - name: Install tox run: python -m pip install tox - name: Eval ${{ matrix.job }} run: tox -e ${{ matrix.job }} check: # This job does nothing and is only used for the branch protection if: always() needs: - test - collateral runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} release: permissions: contents: write needs: - check if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: 3.x - name: Install tox run: python -m pip install tox - name: Run run: tox -e release env: TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/.pre-commit-config.yaml0000644000175100017510000000022715146630546021001 0ustar00runnerrunnerrepos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.12.0 hooks: - id: ruff args: [--fix, --unsafe-fixes] - id: ruff-format ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/.readthedocs.yaml0000644000175100017510000000056515146630546017754 0ustar00runnerrunnerversion: 2 python: install: - path: . extra_requirements: - doc sphinx: configuration: docs/conf.py # required boilerplate readthedocs/readthedocs.org#10401 build: os: ubuntu-lts-latest tools: python: latest # post-checkout job to ensure the clone isn't shallow jaraco/skeleton#114 jobs: post_checkout: - git fetch --unshallow || true ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778427.0 jaraco_packaging-10.4.0/LICENSE0000644000175100017510000000206415146630573015526 0ustar00runnerrunnerMIT License Copyright (c) 2026 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/NEWS.rst0000644000175100017510000001202015146630546016020 0ustar00runnerrunnerv10.4.0 ======= Features -------- - Added ``releases`` option to ``sidebar-links`` directive, generating a link to the GitHub releases page from the ``Source`` URL in project metadata. (#23) v10.3.0 ======= Features -------- - Complete annotations and add ``py.typed`` marker -- by :user:`Avasam` (#20) - Enabled strict type checking. (#20) Bugfixes -------- - Inline the definition of StrPath. (#22) v10.2.3 ======= Bugfixes -------- - Adapt to latest versions of importlib.metadata that don't allow for implicit None values. v10.2.2 ======= Bugfixes -------- - Fixed DeprecationWarning in metadata.hunt_down_url. v10.2.1 ======= Bugfixes -------- - Fixed issue in rendering non-unique keys in print-metadata. v10.2.0 ======= Features -------- - Add script for printing metadata. v10.1.0 ======= Features -------- - Add metadata.extract_email helper. Ref jaraco/jaraco.media#2. v10.0.0 ======= Deprecations and Removals ------------------------- - Moved metadata helpers to metadata module. v9.7.1 ====== Bugfixes -------- - In extract_author, expand the logic to support multiple authors in pyproject.toml form. v9.7.0 ====== Features -------- - Configure Sphinx earlier in 'config-inited', allowing other etxensions to rely on the produced values. (#16) v9.6.0 ====== Features -------- - Add support for other metadata fields since pyproject.toml shuffles things around. (#17) v9.5.0 ====== Features -------- - Add ``metadata.load`` for loading metadata from a source dir with support for a BUILD_ENVIRONMENT setting. Set BUILD_ENVIRONMENT=current to bypass isolation when loading metadata. Ref pypa/build#556. (#556) v9.4.0 ====== Features -------- - Deprecated use of environment variable for isolated builds. The workaround is in the wrong place and should be dealt with upstream. (#11) v9.3.0 ====== Features -------- - Add sidebar-links directive. - Require Python 3.8 or later. v9.2.0 ====== #7, #10, #11: Added environment variable to bypass building metadata for offline builds. v9.1.2 ====== #6: Added minimal test to ``sphinx.packaging``. v9.1.1 ====== Change requirement to ``build[virtualenv]`` as workaround for `pypa/build#266 `_. v9.1.0 ====== Prefer ``build`` to ``pep517`` for loading package metadata. v9.0.0 ====== Use pep517.meta to load package metadata. Adds support for packages without setup.py. Removed info module (and setuptools show command). Removed depends module. Use other packaging tools instead. v8.2.1 ====== Rely on PEP 420 for namespace package. v8.2.0 ====== Inject rst_epilog to include ``|project|`` substitution. v8.1.1 ====== Refresh package metadata. v8.1.0 ====== In ``sphinx`` when loading metadata, trap a ValueError to include the offending value. v8.0.0 ====== Require Python 3.6 or later. 7.0 === Removed 'cheese' package as it was built for a use-case that is no longer needed, depends on deprecated functionality in setuptools, and is causing errors in tests (SSL). 6.2 === Sphinx plugin now declares support for parallel reads (optimistically). 6.1 === Sphinx plugin now exposes ``package_url`` in HTML templates. 6.0 === Switch to `pkgutil namespace technique `_ for the ``jaraco`` namespace. 5.2 === Show command now also honors direct attributes on a Distribution instance. 5.1.1 ===== #2: In Sphinx module, use universal newlines to avoid broken results on Windows. 5.1 === Added ``jaraco.packaging.make-tree`` utility for taking output from pipdeptree and making a tree of it. 5.0 === Drop support for Python 2.6. Re-aligned to use pkg_resources-managed technique for the jaraco namespace, all package of which must elect one technique or another. 4.1 === Use pkgutil for namespace package handling. Experimental process based on pypa/python-packaging-user-guide#265. 4.0 === Remove ``release`` module. 3.2 === Add Python 2.6 support for Sphinx extension. 3.1 === Added Sphinx extension for loading several keys from their package metadata. 3.0 === Removed pmxbot uploader. 2.11 ==== Moved hosting to Github. Add support for retaining the active bookmark after updating to tagged revision for release. 2.10 ==== ``release`` script no longer invokes register prior to the upload. Instead, the user should either set the password in .pypirc (not recommended) or use Setuptools 20.1 and keyring to store the password securely. 2.9 === Add ``show`` distutils command for showing attributes of the distribution. 2.8 === Add ``packaging.depends.load_dependencies``. 2.7 === Added ``--register`` option to ``upload-package`` command. 2.4 === Added ``jaraco.packaging.cheese`` and the ``upload-package`` command from the YouGov project of the same namesake. 2.3 === Add 'dist_commands' to config so projects released with ``jaraco.packaging.release`` can specify which dist commands are run. 2.2 === Added ``depends`` module implementing a ``dependency-tree`` command and also a distutils Command ``dependency_tree``. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0077024 jaraco_packaging-10.4.0/PKG-INFO0000644000175100017510000000745615146630574015631 0ustar00runnerrunnerMetadata-Version: 2.4 Name: jaraco.packaging Version: 10.4.0 Summary: tools to supplement packaging Python releases Author-email: "Jason R. Coombs" License-Expression: MIT Project-URL: Source, https://github.com/jaraco/jaraco.packaging Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Framework :: Sphinx :: Extension Requires-Python: >=3.9 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: build[virtualenv] Requires-Dist: jaraco.context Requires-Dist: sphinx Requires-Dist: domdf-python-tools Provides-Extra: test Requires-Dist: pytest!=8.1.*,>=6; extra == "test" Requires-Dist: types-docutils; extra == "test" Provides-Extra: doc Requires-Dist: sphinx>=3.5; extra == "doc" Requires-Dist: jaraco.packaging>=9.3; extra == "doc" Requires-Dist: rst.linker>=1.9; extra == "doc" Requires-Dist: furo; extra == "doc" Requires-Dist: sphinx-lint; extra == "doc" Provides-Extra: check Requires-Dist: pytest-checkdocs>=2.4; extra == "check" Requires-Dist: pytest-ruff>=0.2.1; sys_platform != "cygwin" and extra == "check" Provides-Extra: cover Requires-Dist: pytest-cov; extra == "cover" Provides-Extra: enabler Requires-Dist: pytest-enabler>=3.4; extra == "enabler" Provides-Extra: type Requires-Dist: pytest-mypy>=1.0.1; extra == "type" Requires-Dist: mypy<1.19; platform_python_implementation == "PyPy" and extra == "type" Requires-Dist: importlib_metadata; extra == "type" Dynamic: license-file .. image:: https://img.shields.io/pypi/v/jaraco.packaging.svg :target: https://pypi.org/project/jaraco.packaging .. image:: https://img.shields.io/pypi/pyversions/jaraco.packaging.svg .. image:: https://github.com/jaraco/jaraco.packaging/actions/workflows/main.yml/badge.svg :target: https://github.com/jaraco/jaraco.packaging/actions?query=workflow%3A%22tests%22 :alt: tests .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json :target: https://github.com/astral-sh/ruff :alt: Ruff .. image:: https://readthedocs.org/projects/jaracopackaging/badge/?version=latest :target: https://jaracopackaging.readthedocs.io/en/latest/?badge=latest .. image:: https://img.shields.io/badge/skeleton-2025-informational :target: https://blog.jaraco.com/skeleton Tools for packaging. sphinx ====== This package provides a Sphinx extension that will inject into the config the following values from the project's package metadata (as presented by distutils): - project (from name) - author - copyright (same as author) - version - release (same as version) - package_url (from url) To enable, include 'jaraco.packaging' in the requirements and add 'jaraco.packaging.sphinx' to the list of extensions in a Sphinx config file:: extensions=['jaraco.packaging.sphinx'] The extension by default builds the project in an isolated environment in order to extract the metadata. For offline builds, set ``BUILD_ENVIRONMENT=current`` and ensure the build dependencies are met in the current environment. Deprecated: To build the documentation offline, provide an already built wheel by setting the environment variable ``JARACO_PACKAGING_SPHINX_WHEEL`` to the path of an existing wheel. make-tree ========= A utility for taking output from ``pipdeptree --json`` and producing a tree rooted at a given package. Usage:: pipdeptree --json | python -m jaraco.packaging.make-tree mypkg metadata ========= A wrapper around ``build.util.project_wheel_metadata`` to enable dowstream packagers to indicate that they need an isolated build. Set the environment variable ``BUILD_ENVIRONMENT=current`` to bypass build isolation and use the current isolation for loading metadata from a project. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/README.rst0000644000175100017510000000435415146630546016214 0ustar00runnerrunner.. image:: https://img.shields.io/pypi/v/jaraco.packaging.svg :target: https://pypi.org/project/jaraco.packaging .. image:: https://img.shields.io/pypi/pyversions/jaraco.packaging.svg .. image:: https://github.com/jaraco/jaraco.packaging/actions/workflows/main.yml/badge.svg :target: https://github.com/jaraco/jaraco.packaging/actions?query=workflow%3A%22tests%22 :alt: tests .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json :target: https://github.com/astral-sh/ruff :alt: Ruff .. image:: https://readthedocs.org/projects/jaracopackaging/badge/?version=latest :target: https://jaracopackaging.readthedocs.io/en/latest/?badge=latest .. image:: https://img.shields.io/badge/skeleton-2025-informational :target: https://blog.jaraco.com/skeleton Tools for packaging. sphinx ====== This package provides a Sphinx extension that will inject into the config the following values from the project's package metadata (as presented by distutils): - project (from name) - author - copyright (same as author) - version - release (same as version) - package_url (from url) To enable, include 'jaraco.packaging' in the requirements and add 'jaraco.packaging.sphinx' to the list of extensions in a Sphinx config file:: extensions=['jaraco.packaging.sphinx'] The extension by default builds the project in an isolated environment in order to extract the metadata. For offline builds, set ``BUILD_ENVIRONMENT=current`` and ensure the build dependencies are met in the current environment. Deprecated: To build the documentation offline, provide an already built wheel by setting the environment variable ``JARACO_PACKAGING_SPHINX_WHEEL`` to the path of an existing wheel. make-tree ========= A utility for taking output from ``pipdeptree --json`` and producing a tree rooted at a given package. Usage:: pipdeptree --json | python -m jaraco.packaging.make-tree mypkg metadata ========= A wrapper around ``build.util.project_wheel_metadata`` to enable dowstream packagers to indicate that they need an isolated build. Set the environment variable ``BUILD_ENVIRONMENT=current`` to bypass build isolation and use the current isolation for loading metadata from a project. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/conftest.py0000644000175100017510000000067015146630546016721 0ustar00runnerrunnerimport subprocess from pathlib import Path import pytest @pytest.fixture def static_wheel(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: subprocess.check_call( ['pip', 'download', '--no-deps', '--dest', str(tmp_path), 'sampleproject'], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL, ) (wheel,) = tmp_path.iterdir() monkeypatch.setenv('JARACO_PACKAGING_SPHINX_WHEEL', str(wheel)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0037026 jaraco_packaging-10.4.0/docs/0000755000175100017510000000000015146630574015450 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/docs/conf.py0000644000175100017510000000304615146630546016751 0ustar00runnerrunnerfrom __future__ import annotations extensions = [ 'sphinx.ext.autodoc', 'jaraco.packaging.sphinx', ] master_doc = "index" html_theme = "furo" # Link dates and other references in the changelog extensions += ['rst.linker'] link_files = { '../NEWS.rst': dict( using=dict(GH='https://github.com'), replace=[ dict( pattern=r'(Issue #|\B#)(?P\d+)', url='{package_url}/issues/{issue}', ), dict( pattern=r'(?m:^((?Pv?\d+(\.\d+){1,2}))\n[-=]+\n)', with_scm='{text}\n{rev[timestamp]:%d %b %Y}\n', ), dict( pattern=r'PEP[- ](?P\d+)', url='https://peps.python.org/pep-{pep_number:0>4}/', ), ], ) } # Be strict about any broken references nitpicky = True nitpick_ignore: list[tuple[str, str]] = [] # Include Python intersphinx mapping to prevent failures # jaraco/skeleton#51 extensions += ['sphinx.ext.intersphinx'] intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), 'sphinx': ('https://www.sphinx-doc.org/en/stable/', None), } # Preserve authored syntax for defaults autodoc_preserve_defaults = True # Add support for linking usernames, PyPI projects, Wikipedia pages github_url = 'https://github.com/' extlinks = { 'user': (f'{github_url}%s', '@%s'), 'pypi': ('https://pypi.org/project/%s', '%s'), 'wiki': ('https://wikipedia.org/wiki/%s', '%s'), } extensions += ['sphinx.ext.extlinks'] # local ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/docs/history.rst0000644000175100017510000000011615146630546017700 0ustar00runnerrunner:tocdepth: 2 .. _changes: History ******* .. include:: ../NEWS (links).rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/docs/index.rst0000644000175100017510000000066615146630546017320 0ustar00runnerrunnerWelcome to |project| documentation! =================================== .. sidebar-links:: :home: :pypi: .. toctree:: :maxdepth: 1 history .. automodule:: jaraco.packaging :members: :undoc-members: :show-inheritance: .. automodule:: jaraco.packaging.sphinx :members: :undoc-members: :show-inheritance: Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1771778428.000703 jaraco_packaging-10.4.0/jaraco/0000755000175100017510000000000015146630574015757 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0057025 jaraco_packaging-10.4.0/jaraco/packaging/0000755000175100017510000000000015146630574017703 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/jaraco/packaging/__init__.py0000644000175100017510000000000015146630546022001 0ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/jaraco/packaging/make-tree.py0000644000175100017510000000270315146630546022130 0ustar00runnerrunner""" Take json output from pipdeptree --json and make it into a tree rooted at the indicated package. """ from __future__ import annotations import itertools import json import sys from collections.abc import Iterable, Mapping from typing import TYPE_CHECKING, Any, TypeVar if TYPE_CHECKING: from typing_extensions import Self _T = TypeVar("_T") def by_package_key( item: Mapping[str, Mapping[str, _T]], ) -> _T: return by_key(item['package']) def by_key(item: Mapping[str, _T]) -> _T: return item['key'] def main() -> None: (root,) = sys.argv[1:] pkgs = Packages.from_defn(json.load(sys.stdin)) json.dump(pkgs.make_tree(root), sys.stdout) class Packages(dict[str, dict[str, Any]]): @classmethod def from_defn(cls, items: Iterable[dict[str, Any]]) -> Self: return cls( (key, next(items)) for key, items in itertools.groupby(items, by_package_key) ) def make_tree(self, target: str) -> dict[str, Any]: if not hasattr(self, 'visited'): self.visited: set[str] = set() root = self[target].copy() if target in self.visited: # short-circuit circular dependencies del root['dependencies'] return root self.visited.add(target) deps_names = map(by_key, root['dependencies']) root['dependencies'] = list(map(self.make_tree, deps_names)) return root if __name__ == '__main__': main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/jaraco/packaging/metadata.py0000644000175100017510000000713015146630546022035 0ustar00runnerrunnerfrom __future__ import annotations import os import re from collections.abc import Iterable from typing import TYPE_CHECKING from build import util if TYPE_CHECKING: from _typeshed import StrPath from importlib_metadata import PackageMetadata from pyproject_hooks import SubprocessRunner def load( source_dir: StrPath, isolated: bool = os.environ.get('BUILD_ENVIRONMENT', 'isolated') == 'isolated', **kwargs: SubprocessRunner, ) -> PackageMetadata: """ Allow overriding the isolation behavior at the enviroment level. """ return util.project_wheel_metadata(source_dir, isolated, **kwargs) def hunt_down_url(meta: PackageMetadata) -> str | None: """ Given project metadata, figure out what the package URL is. >>> hunt_down_url(load('.')) 'https://github.com/jaraco/jaraco.packaging' """ return meta.get('Home-page') or get_best(meta.get_all('Project-URL', ())) def get_best(project_urls: Iterable[str]) -> str | None: lookup = dict(url.split(', ') for url in project_urls) return lookup.get('Source') or lookup.get('Homepage') def get_source_url(meta: PackageMetadata) -> str | None: """ Given project metadata, return the Source URL from Project-URL entries. >>> get_source_url(load('.')) 'https://github.com/jaraco/jaraco.packaging' >>> import email.message >>> get_source_url(email.message.Message()) is None True """ lookup = dict(url.split(', ', 1) for url in meta.get_all('Project-URL', ())) return lookup.get('Source') combo_re = r'["]?(?P\w[\w\s.]*?)["]?\s+<(?P\w+@[\w.]+)>' """The pattern for matching name and email from *-email fields.""" def extract_author(meta: PackageMetadata) -> str: """ Given project metadata, figure out who the author is. The metadata is so irregular, just make some inferences and refine. This form comes from a setup.cfg file or setup.py. >>> meta = {'Author': 'Jason R. Coombs'} >>> extract_author(meta) 'Jason R. Coombs' >>> meta = {'Author': 'Foo Bar, Bing Baz'} >>> extract_author(meta) 'Foo Bar, Bing Baz' This form comes from pyproject.toml converted from the above config. >>> meta = {'Author-email': '"Jason R. Coombs" '} >>> extract_author(meta) 'Jason R. Coombs' >>> meta = {'Author-email': 'Foo Bar , Bing Baz '} >>> extract_author(meta) 'Foo Bar, Bing Baz' """ return meta.get('Author') or ', '.join( match.group('name') for match in re.finditer(combo_re, meta['Author-email']) ) def extract_email(meta: PackageMetadata) -> str: """ Given project metadata, figure out the author's email. The metadata is so irregular, just make some inferences and refine. This form comes from a setup.cfg file or setup.py. >>> meta = {'Author-email': 'jaraco@contoso.com'} >>> extract_email(meta) 'jaraco@contoso.com' >>> meta = {'Author-email': 'foo@bar.name, bing@baz.name'} >>> extract_email(meta) 'foo@bar.name, bing@baz.name' This form comes from pyproject.toml converted from the above config. >>> meta = {'Author-email': '"Jason R. Coombs" ', 'Author': None} >>> extract_email(meta) 'jaraco@contoso.com' >>> meta = {'Author-email': 'Foo Bar , Bing Baz ', 'Author': None} >>> extract_email(meta) 'foo@bar.name, bing@baz.name' """ if '<' not in meta['Author-email']: return meta['Author-email'] return ', '.join( match.group('email') for match in re.finditer(combo_re, meta['Author-email']) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/jaraco/packaging/print-metadata.py0000644000175100017510000000074015146630546023167 0ustar00runnerrunnerfrom typing import TYPE_CHECKING, cast from . import metadata if TYPE_CHECKING: from importlib_metadata._adapters import Message def main() -> None: """ >>> main() Metadata-Version: ... """ # cast: Default PathDistribution.metadata is a Message md = cast("Message", metadata.load('.')) # cannot print(md) due to python/cpython#119650 for key, value in md.items(): print(key, value, sep=': ') if __name__ == '__main__': main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/jaraco/packaging/py.typed0000644000175100017510000000000015146630546021367 0ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/jaraco/packaging/sphinx.py0000644000175100017510000001405215146630546021567 0ustar00runnerrunner""" This module is a Sphinx plugin. Add ``jaraco.packaging.sphinx`` to conf.py, and the setup hook does the rest. >>> 'setup' in globals() True """ from __future__ import annotations import os import warnings from collections.abc import MutableMapping from typing import TYPE_CHECKING, ClassVar import docutils.nodes import docutils.statemachine import domdf_python_tools.stringlist import sphinx.addnodes import sphinx.application import sphinx.config import sphinx.util.docutils from docutils.parsers.rst import directives from jaraco.context import suppress from . import metadata as jp_metadata if TYPE_CHECKING: import importlib_metadata as metadata else: from importlib import metadata def setup(app: sphinx.application.Sphinx) -> dict[str, str | bool]: """ >>> class MockApp: ... def add_config_value(self, *a): pass ... def connect(self, *a): pass ... def add_directive(self, *a): pass >>> result = setup(MockApp()) >>> result['parallel_read_safe'] True """ app.add_config_value('package_url', '', '') app.add_config_value('source_url', '', '') app.connect('config-inited', load_config_from_setup) app.connect('config-inited', configure_substitutions) app.connect('html-page-context', add_package_url) app.add_directive("sidebar-links", SidebarLinksDirective) return dict(version=metadata.version('jaraco.packaging'), parallel_read_safe=True) class SidebarLinksDirective(sphinx.util.docutils.SphinxDirective): """ Directive which adds a toctree to the sidebar containing links to the project home and PyPI repo. """ has_content: ClassVar[bool] = True option_spec = { "pypi": directives.flag, "home": directives.flag, "releases": directives.flag, "caption": directives.unchanged_required, } def run(self) -> list[sphinx.addnodes.only]: """ Create the installation node. >>> from unittest.mock import MagicMock >>> directive = object.__new__(SidebarLinksDirective) >>> directive.state = MagicMock() >>> env = directive.state.document.settings.env >>> env.docname = env.config.master_doc = 'index' >>> env.config.source_url = 'https://github.com/foo/bar' >>> directive.options = {'releases': None} >>> directive.content = [] >>> directive.content_offset = 0 >>> len(directive.run()) # one 'only' node wrapping the toctree 1 >>> env.config.source_url = '' >>> from docutils.parsers.rst import DirectiveError >>> directive.run() Traceback (most recent call last): ... docutils.parsers.rst.DirectiveError """ if self.env.docname != self.env.config.master_doc: return [] body = domdf_python_tools.stringlist.StringList([ ".. toctree::", " :hidden:", ]) with body.with_indent(" ", 1): body.append(f":caption: {self.options.get('caption', 'Links')}") body.blankline() if "home" in self.options: body.append(f"Home <{self.env.config.package_url}>") if "pypi" in self.options: body.append( f"PyPI " ) if "releases" in self.options: source_url = self.env.config.source_url if not source_url: raise self.error( "releases link requires a Source URL in project metadata" ) body.append(f"Releases <{source_url}/releases>") body.extend(self.content) body.blankline() body.blankline() only_node = sphinx.addnodes.only(expr="html") content_node = docutils.nodes.paragraph(rawsource=str(body)) only_node += content_node self.state.nested_parse( docutils.statemachine.StringList(body), self.content_offset, content_node ) return [only_node] @suppress(KeyError) def _load_metadata_from_wheel() -> metadata.PackageMetadata: """ If indicated by an environment variable, expect the metadata to be present in a wheel and load it from there, avoiding the build process. Ref jaraco/jaraco.packaging#7. >>> _load_metadata_from_wheel() >>> getfixture('static_wheel') >>> meta = _load_metadata_from_wheel() >>> meta['Name'] 'sampleproject' """ wheel = os.environ['JARACO_PACKAGING_SPHINX_WHEEL'] warnings.warn( "JARACO_PACKAGING_SPHINX_WHEEL is deprecated; " "use BUILD_ENVIRONMENT=current instead", DeprecationWarning, ) (dist,) = metadata.distributions(path=[wheel]) assert dist.metadata is not None return dist.metadata def load_config_from_setup( app: sphinx.application.Sphinx, config: sphinx.config.Config ) -> None: """ Replace values in app.config from package metadata >>> class MockConfig: ... pass >>> class MockApp: ... confdir = 'docs' >>> config = MockConfig() >>> load_config_from_setup(MockApp(), config) >>> config.source_url 'https://github.com/jaraco/jaraco.packaging' """ # for now, assume project root is one level up root = os.path.join(app.confdir, '..') meta = _load_metadata_from_wheel() or jp_metadata.load(root) config.project = meta['Name'] config.version = config.release = meta['Version'] config.package_url = jp_metadata.hunt_down_url(meta) config.source_url = jp_metadata.get_source_url(meta) config.author = config.copyright = jp_metadata.extract_author(meta) def configure_substitutions(app: object, config: sphinx.config.Config) -> None: epilogs = config.rst_epilog, f'.. |project| replace:: {config.project}' config.rst_epilog = '\n'.join(filter(None, epilogs)) def add_package_url( app: sphinx.application.Sphinx, pagename: object, templatename: object, context: MutableMapping[str, str], doctree: object, ) -> None: context['package_url'] = app.config.package_url ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0067024 jaraco_packaging-10.4.0/jaraco.packaging.egg-info/0000755000175100017510000000000015146630574021374 5ustar00runnerrunner././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778427.0 jaraco_packaging-10.4.0/jaraco.packaging.egg-info/PKG-INFO0000644000175100017510000000745615146630573022504 0ustar00runnerrunnerMetadata-Version: 2.4 Name: jaraco.packaging Version: 10.4.0 Summary: tools to supplement packaging Python releases Author-email: "Jason R. Coombs" License-Expression: MIT Project-URL: Source, https://github.com/jaraco/jaraco.packaging Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Framework :: Sphinx :: Extension Requires-Python: >=3.9 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: build[virtualenv] Requires-Dist: jaraco.context Requires-Dist: sphinx Requires-Dist: domdf-python-tools Provides-Extra: test Requires-Dist: pytest!=8.1.*,>=6; extra == "test" Requires-Dist: types-docutils; extra == "test" Provides-Extra: doc Requires-Dist: sphinx>=3.5; extra == "doc" Requires-Dist: jaraco.packaging>=9.3; extra == "doc" Requires-Dist: rst.linker>=1.9; extra == "doc" Requires-Dist: furo; extra == "doc" Requires-Dist: sphinx-lint; extra == "doc" Provides-Extra: check Requires-Dist: pytest-checkdocs>=2.4; extra == "check" Requires-Dist: pytest-ruff>=0.2.1; sys_platform != "cygwin" and extra == "check" Provides-Extra: cover Requires-Dist: pytest-cov; extra == "cover" Provides-Extra: enabler Requires-Dist: pytest-enabler>=3.4; extra == "enabler" Provides-Extra: type Requires-Dist: pytest-mypy>=1.0.1; extra == "type" Requires-Dist: mypy<1.19; platform_python_implementation == "PyPy" and extra == "type" Requires-Dist: importlib_metadata; extra == "type" Dynamic: license-file .. image:: https://img.shields.io/pypi/v/jaraco.packaging.svg :target: https://pypi.org/project/jaraco.packaging .. image:: https://img.shields.io/pypi/pyversions/jaraco.packaging.svg .. image:: https://github.com/jaraco/jaraco.packaging/actions/workflows/main.yml/badge.svg :target: https://github.com/jaraco/jaraco.packaging/actions?query=workflow%3A%22tests%22 :alt: tests .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json :target: https://github.com/astral-sh/ruff :alt: Ruff .. image:: https://readthedocs.org/projects/jaracopackaging/badge/?version=latest :target: https://jaracopackaging.readthedocs.io/en/latest/?badge=latest .. image:: https://img.shields.io/badge/skeleton-2025-informational :target: https://blog.jaraco.com/skeleton Tools for packaging. sphinx ====== This package provides a Sphinx extension that will inject into the config the following values from the project's package metadata (as presented by distutils): - project (from name) - author - copyright (same as author) - version - release (same as version) - package_url (from url) To enable, include 'jaraco.packaging' in the requirements and add 'jaraco.packaging.sphinx' to the list of extensions in a Sphinx config file:: extensions=['jaraco.packaging.sphinx'] The extension by default builds the project in an isolated environment in order to extract the metadata. For offline builds, set ``BUILD_ENVIRONMENT=current`` and ensure the build dependencies are met in the current environment. Deprecated: To build the documentation offline, provide an already built wheel by setting the environment variable ``JARACO_PACKAGING_SPHINX_WHEEL`` to the path of an existing wheel. make-tree ========= A utility for taking output from ``pipdeptree --json`` and producing a tree rooted at a given package. Usage:: pipdeptree --json | python -m jaraco.packaging.make-tree mypkg metadata ========= A wrapper around ``build.util.project_wheel_metadata`` to enable dowstream packagers to indicate that they need an isolated build. Set the environment variable ``BUILD_ENVIRONMENT=current`` to bypass build isolation and use the current isolation for loading metadata from a project. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778427.0 jaraco_packaging-10.4.0/jaraco.packaging.egg-info/SOURCES.txt0000644000175100017510000000115615146630573023262 0ustar00runnerrunner.coveragerc .editorconfig .pre-commit-config.yaml .readthedocs.yaml LICENSE NEWS.rst README.rst conftest.py mypy.ini pyproject.toml pytest.ini ruff.toml towncrier.toml tox.ini .github/workflows/main.yml docs/conf.py docs/history.rst docs/index.rst jaraco.packaging.egg-info/PKG-INFO jaraco.packaging.egg-info/SOURCES.txt jaraco.packaging.egg-info/dependency_links.txt jaraco.packaging.egg-info/requires.txt jaraco.packaging.egg-info/top_level.txt jaraco/packaging/__init__.py jaraco/packaging/make-tree.py jaraco/packaging/metadata.py jaraco/packaging/print-metadata.py jaraco/packaging/py.typed jaraco/packaging/sphinx.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778427.0 jaraco_packaging-10.4.0/jaraco.packaging.egg-info/dependency_links.txt0000644000175100017510000000000115146630573025441 0ustar00runnerrunner ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778427.0 jaraco_packaging-10.4.0/jaraco.packaging.egg-info/requires.txt0000644000175100017510000000063615146630573024000 0ustar00runnerrunnerbuild[virtualenv] jaraco.context sphinx domdf-python-tools [check] pytest-checkdocs>=2.4 [check:sys_platform != "cygwin"] pytest-ruff>=0.2.1 [cover] pytest-cov [doc] sphinx>=3.5 jaraco.packaging>=9.3 rst.linker>=1.9 furo sphinx-lint [enabler] pytest-enabler>=3.4 [test] pytest!=8.1.*,>=6 types-docutils [type] pytest-mypy>=1.0.1 importlib_metadata [type:platform_python_implementation == "PyPy"] mypy<1.19 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778427.0 jaraco_packaging-10.4.0/jaraco.packaging.egg-info/top_level.txt0000644000175100017510000000000715146630573024122 0ustar00runnerrunnerjaraco ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/mypy.ini0000644000175100017510000000056615146630546016225 0ustar00runnerrunner[mypy] # Is the project well-typed? strict = True # Early opt-in even when strict = False warn_unused_ignores = True warn_redundant_casts = True enable_error_code = ignore-without-code # Support namespace packages per https://github.com/python/mypy/issues/14057 explicit_package_bases = True disable_error_code = # Disable due to many false positives overload-overlap, ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/pyproject.toml0000644000175100017510000000303315146630546017432 0ustar00runnerrunner[build-system] requires = [ "setuptools>=77", "setuptools_scm[toml]>=3.4.1", # jaraco/skeleton#174 "coherent.licensed", ] build-backend = "setuptools.build_meta" [project] name = "jaraco.packaging" authors = [ { name = "Jason R. Coombs", email = "jaraco@jaraco.com" }, ] description = "tools to supplement packaging Python releases" readme = "README.rst" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Framework :: Sphinx :: Extension", ] requires-python = ">=3.9" license = "MIT" dependencies = [ # virtualenv extra due to pypa/build#266 "build[virtualenv]", "jaraco.context", "sphinx", "domdf-python-tools", ] dynamic = ["version"] [project.urls] Source = "https://github.com/jaraco/jaraco.packaging" [project.optional-dependencies] test = [ # upstream "pytest >= 6, != 8.1.*", # local "types-docutils", ] doc = [ # upstream "sphinx >= 3.5", "jaraco.packaging >= 9.3", "rst.linker >= 1.9", "furo", "sphinx-lint", # local ] check = [ "pytest-checkdocs >= 2.4", "pytest-ruff >= 0.2.1; sys_platform != 'cygwin'", ] cover = [ "pytest-cov", ] enabler = [ "pytest-enabler >= 3.4", ] type = [ # upstream "pytest-mypy >= 1.0.1", ## workaround for python/mypy#20454 "mypy < 1.19; python_implementation == 'PyPy'", # local # PackageMetadata Protocol doesn't have `get` method until Python 3.12 # But this is a type-checking only issue. "importlib_metadata", ] [tool.setuptools_scm] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/pytest.ini0000644000175100017510000000117515146630546016554 0ustar00runnerrunner[pytest] norecursedirs=dist build .tox .eggs addopts= --doctest-modules --import-mode importlib consider_namespace_packages=true filterwarnings= ## upstream # Ensure ResourceWarnings are emitted default::ResourceWarning # realpython/pytest-mypy#152 ignore:'encoding' argument not specified::pytest_mypy # python/cpython#100750 ignore:'encoding' argument not specified::platform # pypa/build#615 ignore:'encoding' argument not specified::build.env # dateutil/dateutil#1284 ignore:datetime.datetime.utcfromtimestamp:DeprecationWarning:dateutil.tz.tz ## end upstream ignore:JARACO_PACKAGING_SPHINX_WHEEL is deprecated ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/ruff.toml0000644000175100017510000000226315146630546016361 0ustar00runnerrunner[lint] extend-select = [ # upstream "C901", # complex-structure "I", # isort "PERF401", # manual-list-comprehension # Ensure modern type annotation syntax and best practices # Not including those covered by type-checkers or exclusive to Python 3.11+ "FA", # flake8-future-annotations "F404", # late-future-import "PYI", # flake8-pyi "UP006", # non-pep585-annotation "UP007", # non-pep604-annotation "UP010", # unnecessary-future-import "UP035", # deprecated-import "UP037", # quoted-annotation "UP043", # unnecessary-default-type-args # local ] ignore = [ # upstream # Typeshed rejects complex or non-literal defaults for maintenance and testing reasons, # irrelevant to this project. "PYI011", # typed-argument-default-in-stub # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "W191", "E111", "E114", "E117", "D206", "D300", "Q000", "Q001", "Q002", "Q003", "COM812", "COM819", # local ] [format] # Enable preview to get hugged parenthesis unwrapping and other nice surprises # See https://github.com/jaraco/skeleton/pull/133#issuecomment-2239538373 preview = true # https://docs.astral.sh/ruff/settings/#format_quote-style quote-style = "preserve" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1771778428.0077024 jaraco_packaging-10.4.0/setup.cfg0000644000175100017510000000004615146630574016341 0ustar00runnerrunner[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/towncrier.toml0000644000175100017510000000013715146630546017431 0ustar00runnerrunner[tool.towncrier] title_format = "{version}" directory = "newsfragments" # jaraco/skeleton#184 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771778406.0 jaraco_packaging-10.4.0/tox.ini0000644000175100017510000000245415146630546016037 0ustar00runnerrunner[testenv] description = perform primary checks (tests, style, types, coverage) deps = setenv = PYTHONWARNDEFAULTENCODING = 1 commands = pytest {posargs} usedevelop = True extras = test check cover enabler type [testenv:diffcov] description = run tests and check that diff from main is covered deps = {[testenv]deps} diff-cover commands = pytest {posargs} --cov-report xml diff-cover coverage.xml --compare-branch=origin/main --html-report diffcov.html diff-cover coverage.xml --compare-branch=origin/main --fail-under=100 [testenv:docs] description = build the documentation extras = doc test changedir = docs commands = python -m sphinx -W --keep-going . {toxinidir}/build/html python -m sphinxlint [testenv:finalize] description = assemble changelog and tag a release skip_install = True deps = towncrier jaraco.develop >= 7.23 pass_env = * commands = python -m jaraco.develop.finalize [testenv:release] description = publish the package to PyPI and GitHub skip_install = True deps = build twine>=3 jaraco.develop>=7.1 pass_env = TWINE_PASSWORD GITHUB_TOKEN setenv = TWINE_USERNAME = {env:TWINE_USERNAME:__token__} commands = python -c "import shutil; shutil.rmtree('dist', ignore_errors=True)" python -m build python -m twine upload dist/* python -m jaraco.develop.create-github-release