Skip to content

Commit ae9865c

Browse files
committed
Merge main, full === detection, local version tests
2 parents 1ad6dd8 + 69307a3 commit ae9865c

26 files changed

Lines changed: 2962 additions & 474 deletions

.readthedocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ version: 2
88
build:
99
os: ubuntu-24.04
1010
tools:
11-
python: "3.13"
11+
python: "3.14"
1212
commands:
1313
- asdf plugin add uv
1414
- asdf install uv latest

docs/conf.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
"sphinx.ext.doctest",
2222
"sphinx.ext.extlinks",
2323
"sphinx.ext.intersphinx",
24-
"sphinx_toolbox.more_autodoc.autotypeddict",
2524
]
2625

2726
# General information about the project.

docs/dependency_groups.rst

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
Dependency Groups
2+
=================
3+
4+
.. currentmodule:: packaging.dependency_groups
5+
6+
Package data as defined in ``pyproject.toml`` may include lists of dependencies
7+
in named groups. This is described by the
8+
:ref:`dependency groups specification <pypug:dependency-groups>`, which defines
9+
the ``[dependency-groups]`` table.
10+
11+
This module provides tools for resolving group names to lists of requirements,
12+
most notably expanding ``include-group`` directives.
13+
14+
Usage
15+
-----
16+
17+
Two primary interfaces are offered. An object-based one which caches results and
18+
provides ``Requirements`` as its results:
19+
20+
.. doctest::
21+
22+
>>> from packaging.dependency_groups import DependencyGroupResolver
23+
>>> coverage = ["coverage"]
24+
>>> test = ["pytest", {"include-group": "coverage"}]
25+
>>> # A resolver is defined on a mapping of group names to group data, as
26+
>>> # you might get by loading the [dependency-groups] TOML table.
27+
>>> resolver = DependencyGroupResolver({"test": test, "coverage": coverage})
28+
>>> # resolvers support expanding group names to Requirements
29+
>>> resolver.resolve("coverage")
30+
(<Requirement('coverage')>,)
31+
>>> resolver.resolve("test")
32+
(<Requirement('pytest')>, <Requirement('coverage')>)
33+
>>> # resolvers can also be used to lookup the dependency groups without
34+
>>> # expanding includes
35+
>>> resolver.lookup("test")
36+
(<Requirement('pytest')>, DependencyGroupInclude('coverage'))
37+
38+
And a simpler functional interface which responds with strings:
39+
40+
.. doctest::
41+
42+
>>> from packaging.dependency_groups import resolve_dependency_groups
43+
>>> coverage = ["coverage"]
44+
>>> test = ["pytest", {"include-group": "coverage"}]
45+
>>> groups = {"test": test, "coverage": coverage}
46+
>>> resolve_dependency_groups(groups, "test")
47+
('pytest', 'coverage')
48+
49+
Reference
50+
---------
51+
52+
Functional Interface
53+
''''''''''''''''''''
54+
55+
.. autofunction:: resolve_dependency_groups
56+
57+
58+
Object Model Interface
59+
''''''''''''''''''''''
60+
61+
.. autoclass:: DependencyGroupInclude
62+
:members:
63+
64+
.. autoclass:: DependencyGroupResolver
65+
:members:
66+
67+
Exceptions
68+
''''''''''
69+
70+
.. autoclass:: DuplicateGroupNames
71+
:members:
72+
73+
.. autoclass:: CyclicDependencyGroup
74+
:members:
75+
76+
.. autoclass:: InvalidDependencyGroupObject
77+
:members:

docs/direct_url.rst

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
Direct URLs
2+
===========
3+
4+
.. currentmodule:: packaging.direct_url
5+
6+
Parse and validate `direct_url.json files <https://packaging.python.org/en/latest/specifications/direct-url/>`_.
7+
8+
Usage
9+
-----
10+
11+
.. code-block:: python
12+
13+
import json
14+
from pathlib import Path
15+
16+
from packaging.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
17+
18+
# A VCS direct URL
19+
vcs_direct_url = DirectUrl(
20+
url="https://git.example.com/repo.git",
21+
vcs_info=VcsInfo(
22+
vcs="git",
23+
commit_id="2df7bdd8dfef7b879390b9fc4016f02af2f118d4",
24+
requested_revision="1.1.0",
25+
),
26+
)
27+
28+
# An archive direct URL
29+
archive_direct_url = DirectUrl(
30+
url="https://example.com/archive.tar.gz",
31+
archive_info=ArchiveInfo(
32+
hashes={
33+
"sha256": "dc321a1c18a37b5438424ef3714524229dab5f4f78b297671359426fef51be6c"
34+
}
35+
),
36+
)
37+
38+
# A local editable direct URL
39+
archive_direct_url = DirectUrl(
40+
url="file:///home/project/example",
41+
dir_info=DirInfo(
42+
editable=True,
43+
),
44+
)
45+
46+
# Serialization to JSON
47+
Path("/tmp/direct_url.json").write_text(
48+
json.dumps(vcs_direct_url.to_dict()), encoding="utf-8"
49+
)
50+
51+
# Load from JSON. The resulting DirectUrl object is validated against the
52+
# specification, else a DirectUrlalidationError is raised
53+
direct_url = DirectUrl.from_dict(
54+
json.loads(Path("/tmp/direct_url.json").read_text(encoding="utf-8"))
55+
)
56+
57+
# You can validate a manually constructed DirectUrl class
58+
vcs_direct_url.validate()
59+
60+
61+
Reference
62+
---------
63+
64+
.. autoclass:: DirectUrl
65+
:members: from_dict, to_dict, validate
66+
:exclude-members: __init__, __new__
67+
68+
.. class:: ArchiveInfo
69+
70+
.. class:: DirInfo
71+
72+
.. class:: VcsInfo
73+
74+
The following exception may be raised by this module:
75+
76+
.. autoexception:: DirectUrlValidationError
77+
:exclude-members: __init__, __new__

docs/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ The ``packaging`` library uses calendar-based versioning (``YY.N``).
3131
metadata
3232
tags
3333
pylock
34+
direct_url
35+
dependency_groups
3436
utils
3537

3638
.. toctree::

docs/licenses.rst

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,5 @@ as `defined in PEP 639 <https://peps.python.org/pep-0639/#spdx>`__.
1212
Reference
1313
---------
1414

15-
.. class:: NormalizedLicenseExpression
16-
17-
A :class:`typing.NewType` of :class:`str`, representing a normalized
18-
License-Expression.
19-
20-
21-
.. exception:: InvalidLicenseExpression
22-
23-
Raised when a License-Expression is invalid.
24-
25-
26-
.. function:: canonicalize_license_expression(raw_license_expression)
27-
28-
This function takes a valid License-Expression, and returns the normalized form of it.
29-
30-
The return type is typed as :class:`NormalizedLicenseExpression`. This allows type
31-
checkers to help require that a string has passed through this function
32-
before use.
33-
34-
:param str raw_license_expression: The License-Expression to canonicalize.
35-
:raises InvalidLicenseExpression: If the License-Expression is invalid due to an
36-
invalid/unknown license identifier or invalid syntax.
37-
38-
.. doctest::
39-
40-
>>> from packaging.licenses import canonicalize_license_expression
41-
>>> canonicalize_license_expression("mit")
42-
'MIT'
43-
>>> canonicalize_license_expression("mit and (apache-2.0 or bsd-2-clause)")
44-
'MIT AND (Apache-2.0 OR BSD-2-Clause)'
45-
>>> canonicalize_license_expression("(mit")
46-
Traceback (most recent call last):
47-
...
48-
InvalidLicenseExpression: Invalid license expression: '(mit'
49-
>>> canonicalize_license_expression("Use-it-after-midnight")
50-
Traceback (most recent call last):
51-
...
52-
InvalidLicenseExpression: Unknown license: 'Use-it-after-midnight'
15+
.. automodule:: packaging.licenses
16+
:members:

docs/metadata.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Low Level Interface
4747

4848
.. autoclass:: packaging.metadata.RawMetadata
4949
:members:
50+
:undoc-members:
5051

5152
.. autofunction:: packaging.metadata.parse_email
5253

0 commit comments

Comments
 (0)