Lock Files

Parse and validate pylock.toml files.

Usage

import tomllib
from pathlib import Path

from packaging.pylock import Package, PackageWheel, Pylock, is_valid_pylock_path
from packaging.utils import NormalizedName
from packaging.version import Version

# validate a pylock file name
assert is_valid_pylock_path(Path("pylock.example.toml"))

# parse and validate pylock file
toml_dict = tomllib.loads(Path("pylock.toml").read_text(encoding="utf-8"))
pylock = Pylock.from_dict(toml_dict)
# the resulting pylock object is validated against the specification,
# else a PylockValidationError is raised

# generate a pylock file
pylock = Pylock(
    lock_version=Version("1.0"),
    created_by="some_tool",
    packages=[
        Package(
            name=NormalizedName("example-package"),
            version=Version("1.0.0"),
            wheels=[
                PackageWheel(
                    url="https://example.com/example_package-1.0.0-py3-none-any.whl",
                    hashes={"sha256": "0fd.."},
                )
            ],
        )
    ],
)
toml_dict = pylock.to_dict()
# use a third-party library to serialize to TOML

# you can validate a manually constructed Pylock class
pylock.validate()

# select packages to install for the current environment
for package, artifact in pylock.select():
    print(f"Install {package.name} from {artifact}")

Validation

Pylock.from_dict() and Pylock.validate() check the structure of the lock file against the specification. Required fields must be present, fields must have the expected types, package and extra names must be normalized, and versions, specifiers and markers must parse. Each package must have exactly one source: distribution files (sdist or wheels), or one of vcs, directory or archive. Wheel and sdist filenames must be parseable (see parse_wheel_filename() and parse_sdist_filename()) and match the package name and version.

Validation stops at the structure. URL and path fields, including packages.index, are stored as-is. They are not checked to be valid URLs or paths, and relative paths are not resolved against the location of the lock file. A wheel or sdist entry with no name takes its filename from the last component of its path or url; nothing else is read from these fields. hashes tables must be non-empty and their values must be strings, but algorithm names and digest formats are not checked. Nothing is downloaded, so checking hashes and sizes against the actual artifacts is up to the caller.

Reference

packaging.pylock.is_valid_pylock_path(path)

Check if the given path is a valid pylock file path.

Parameters:

path (pathlib.Path)

Return type:

bool

The following frozen keyword-only dataclasses are used to represent the structure of a pylock file. The attributes correspond to the fields in the pylock file specification.

class packaging.pylock.Pylock

A class representing a pylock file.

classmethod from_dict(d, /)

Create and validate a Pylock instance from a TOML dictionary.

Raises PylockValidationError if the input data is not spec-compliant.

Parameters:

d (Mapping[str, Any])

Return type:

Self

to_dict()

Convert the Pylock instance to a TOML dictionary.

Return type:

Mapping[str, Any]

validate()

Validate the Pylock instance against the specification.

Raises PylockValidationError otherwise.

Return type:

None

select(*, environment=None, tags=None, extras=None, dependency_groups=None, prefer_sdist_predicate=None)

Select what to install from the lock file.

The environment and tags parameters represent the environment being selected for. If unspecified, packaging.markers.default_environment() and packaging.tags.sys_tags() are used.

The extras parameter represents the extras to install.

The dependency_groups parameter represents the groups to install. If unspecified, the default groups are used.

The prefer_sdist_predicate parameter is called for packages with a source distribution. If it returns True, the source distribution is selected before attempting wheel compatibility. If no source distribution is available, wheel selection proceeds as usual without calling the predicate.

This method must be used on valid Pylock instances (i.e. one obtained from Pylock.from_dict() or if constructed manually, after calling Pylock.validate()).

Added in version 26.1.

Changed in version 26.3: Added the prefer_sdist_predicate parameter.

Parameters:
  • environment (Environment | None)

  • tags (Sequence[Tag] | None)

  • extras (Collection[str] | None)

  • dependency_groups (Collection[str] | None)

  • prefer_sdist_predicate (Callable[[NormalizedName], bool] | None)

Return type:

Iterator[tuple[Package, PackageVcs | PackageDirectory | PackageArchive | PackageWheel | PackageSdist]]

class packaging.pylock.Package
class packaging.pylock.PackageWheel
class packaging.pylock.PackageSdist
class packaging.pylock.PackageArchive
class packaging.pylock.PackageVcs
class packaging.pylock.PackageDirectory

The following exceptions may be raised by this module:

exception packaging.pylock.PylockValidationError

Raised when when input data is not spec-compliant.

exception packaging.pylock.PylockUnsupportedVersionError

Raised when encountering an unsupported lock_version.

exception packaging.pylock.PylockSelectError

Base exception for errors raised by Pylock.select().

Added in version 26.1.