Skip to content

Commit bc61305

Browse files
committed
pylock: add documentation
1 parent 4f310b2 commit bc61305

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The ``packaging`` library uses calendar-based versioning (``YY.N``).
3030
requirements
3131
metadata
3232
tags
33+
pylock
3334
utils
3435

3536
.. toctree::

docs/pylock.rst

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
Lock Files
2+
==========
3+
4+
.. currentmodule:: packaging.pylock
5+
6+
Parse and validate `pylock.toml files <https://packaging.python.org/en/latest/specifications/pylock-toml/>`_.
7+
8+
Usage
9+
-----
10+
11+
.. code-block:: python
12+
13+
import tomllib
14+
from pathlib import Path
15+
16+
from packaging.pylock import Package, PackageWheel, Pylock
17+
from packaging.utils import NormalizedName
18+
from packaging.version import Version
19+
20+
# validate a pylock file name
21+
assert is_valid_pylock_path(Path("pylock.example.toml"))
22+
23+
# parse and validate pylock file
24+
toml_dict = tomllib.loads(Path("pylock.toml").read_text(encoding="utf-8"))
25+
pylock = PyLock.from_dict(toml_dict)
26+
# the resulting pylock object is validated against the specification,
27+
# else a PylockValidationError is raised
28+
29+
# generate a pylock file
30+
pylock = Pylock(
31+
lock_version=Version("1.0"),
32+
created_by="some_tool",
33+
packages=[
34+
Package(
35+
name=NormalizedName("example-package"),
36+
version=Version("1.0.0"),
37+
wheels=[
38+
PackageWheel(
39+
url="https://example.com/example_package-1.0.0-py3-none-any.whl",
40+
hashes={"sha256": "0fd.."},
41+
)
42+
],
43+
)
44+
],
45+
)
46+
toml_dict = pylock.to_dict()
47+
# use a third-party library to serialize to TOML
48+
49+
# you can validate a manually constructed Pylock class
50+
pylock.validate()
51+
52+
Reference
53+
---------
54+
55+
.. autofunction:: is_valid_pylock_path
56+
57+
The following frozen keyword-only dataclasses are used to represent the
58+
structure of a pylock file. The attributes correspond to the fields in the
59+
pylock file specification.
60+
61+
.. autoclass:: Pylock
62+
:members: from_dict, to_dict, validate
63+
:exclude-members: __init__, __new__
64+
65+
.. class:: Package
66+
67+
.. class:: PackageWheel
68+
69+
.. class:: PackageSdist
70+
71+
.. class:: PackageArchive
72+
73+
.. class:: PackageVcs
74+
75+
.. class:: PackageDirectory
76+
77+
The following exception may be raised by this module:
78+
79+
.. autoexception:: PylockValidationError
80+
:exclude-members: __init__, __new__
81+
82+
.. autoexception:: PylockUnsupportedVersionError
83+
:exclude-members: __init__, __new__

src/packaging/pylock.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self: ...
5656

5757

5858
def is_valid_pylock_path(path: Path) -> bool:
59+
"""Check if the given path is a valid pylock file path."""
5960
return path.name == "pylock.toml" or bool(_PYLOCK_FILE_NAME_RE.match(path.name))
6061

6162

@@ -233,6 +234,8 @@ def _validate_hashes(hashes: Mapping[str, Any]) -> Mapping[str, Any]:
233234

234235

235236
class PylockValidationError(Exception):
237+
"""Raised when when input data is not spec-compliant."""
238+
236239
context: str | None = None
237240
message: str
238241

@@ -266,7 +269,7 @@ def __init__(self, key: str) -> None:
266269

267270

268271
class PylockUnsupportedVersionError(PylockValidationError):
269-
pass
272+
"""Raised when encountering an unsupported `lock_version`."""
270273

271274

272275
@dataclass(frozen=True, init=False)
@@ -549,6 +552,8 @@ def is_direct(self) -> bool:
549552

550553
@dataclass(frozen=True, init=False)
551554
class Pylock:
555+
"""A class representing a pylock file."""
556+
552557
lock_version: Version
553558
environments: Sequence[Marker] | None = None
554559
requires_python: SpecifierSet | None = None
@@ -608,11 +613,19 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:
608613

609614
@classmethod
610615
def from_dict(cls, d: Mapping[str, Any]) -> Self:
616+
"""Create and validate a Pylock instance from a TOML dictionary.
617+
618+
Raises :class:`PylockValidationError` if the input data is not
619+
spec-compliant.
620+
"""
611621
return cls._from_dict(d)
612622

613623
def to_dict(self) -> Mapping[str, Any]:
624+
"""Convert the Pylock instance to a TOML dictionary."""
614625
return dataclasses.asdict(self, dict_factory=_toml_dict_factory)
615626

616627
def validate(self) -> None:
617-
"""Validate the Pylock instance against the specification."""
628+
"""Validate the Pylock instance against the specification.
629+
630+
Raises :class:`PylockValidationError` otherwise."""
618631
self.from_dict(self.to_dict())

0 commit comments

Comments
 (0)