Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 2 additions & 32 deletions docs/pylock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,35 +81,5 @@ to the caller.
Reference
---------

.. autofunction:: is_valid_pylock_path

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.

.. autoclass:: Pylock
:members: from_dict, to_dict, validate, select
:exclude-members: __init__, __new__

.. class:: Package

.. class:: PackageWheel

.. class:: PackageSdist

.. class:: PackageArchive

.. class:: PackageVcs

.. class:: PackageDirectory

The following exceptions may be raised by this module:

.. autoexception:: PylockValidationError
:exclude-members: __init__, __new__

.. autoexception:: PylockUnsupportedVersionError
:exclude-members: __init__, __new__

.. autoexception:: PylockSelectError
:exclude-members: __init__, __new__
.. automodule:: packaging.pylock
:members:
69 changes: 2 additions & 67 deletions docs/requirements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,70 +72,5 @@ Usage
Reference
---------

.. class:: Requirement(requirement_string)

This class abstracts handling the details of a requirement for a project.
Each requirement will be parsed according to the specification.

.. versionadded:: 16.1

.. versionchanged:: 22.0
Added equality (``__eq__``) and hashing (``__hash__``) so requirements
can be compared and stored in sets / dicts.

.. versionchanged:: 23.2
Equality and hashing began canonicalizing requirement names, so
requirements whose names differ only by normalization (e.g.
``Requirement("Foo")`` vs ``Requirement("foo")``) now compare and hash
equal.

Instances are safe to serialize with :mod:`pickle`. They use a stable
format so the same pickle can be loaded in future packaging releases.

.. versionchanged:: 26.2

Added a stable pickle format. Pickles created with packaging 26.2+ can
be unpickled with future releases. Backward compatibility with pickles
from packaging < 26.2 is supported but may be removed in a future
release.

.. versionchanged:: 26.3

The dedicated pickle support introduced in 26.2 did not preserve the
specifier's explicit :attr:`~packaging.specifiers.SpecifierSet.prereleases`
override; it is now included again.

Equality and hashing normalize extras and equivalent specifiers. The
string representation still preserves the parsed name and extras
spelling.

:param str requirement_string: The string representation of a requirement.
:raises InvalidRequirement: If the given ``requirement_string`` is not parseable,
then this exception will be raised.

.. attribute:: name

The name of the requirement.

.. attribute:: url

The URL, if any, where to download the requirement from. Can be None.

.. attribute:: extras

A set of extras that the requirement specifies.

.. attribute:: specifier

A :class:`~.SpecifierSet` of the version specified by the requirement.

.. attribute:: marker

A :class:`~.Marker` of the marker for the requirement. Can be None.

.. exception:: InvalidRequirement

Raised when attempting to create a :class:`Requirement` with a string that
does not conform to the specification.

.. versionadded:: 16.1
.. automodule:: packaging.requirements
:members:
86 changes: 85 additions & 1 deletion src/packaging/pylock.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
"""Read, validate, and select from pylock files.

The public data model classes are frozen, keyword-only dataclasses whose
attributes correspond to fields in the pylock file specification.
"""

from __future__ import annotations

import dataclasses
Expand Down Expand Up @@ -323,6 +329,16 @@ class PylockSelectError(Exception):

@dataclass(frozen=True, kw_only=True, slots=True)
class PackageVcs:
"""A package installed from a version control system.

:ivar str type: The version control system type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This :ivar stuff isn't used anywhere else and it pollutes the docstring such that help() becomes less readable.

:ivar str | None url: The repository URL, if one is provided.
:ivar str | None path: The repository path, if one is provided.
:ivar str | None requested_revision: The requested revision, if any.
:ivar str commit_id: The resolved commit identifier.
:ivar str | None subdirectory: A repository subdirectory, if selected.
"""

type: str
url: str | None = None
path: str | None = None
Expand All @@ -346,6 +362,13 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:

@dataclass(frozen=True, kw_only=True, slots=True)
class PackageDirectory:
"""A package installed from a local directory.

:ivar str path: The path to the package directory.
:ivar bool | None editable: Whether the package is installed editable.
:ivar str | None subdirectory: A package subdirectory, if selected.
"""

path: str
editable: bool | None = None
subdirectory: str | None = None
Expand All @@ -361,6 +384,16 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:

@dataclass(frozen=True, kw_only=True, slots=True)
class PackageArchive:
"""A package installed from an archive.

:ivar str | None url: The archive URL, if one is provided.
:ivar str | None path: The archive path, if one is provided.
:ivar int | None size: The archive size in bytes, if known.
:ivar datetime.datetime | None upload_time: The archive upload time, if known.
:ivar Mapping[str, str] hashes: Hashes for the archive.
:ivar str | None subdirectory: A package subdirectory, if selected.
"""

url: str | None = None
path: str | None = None
size: int | None = None
Expand All @@ -384,6 +417,16 @@ def _from_dict(cls, d: Mapping[str, Any]) -> Self:

@dataclass(frozen=True, kw_only=True, slots=True)
class PackageSdist:
"""A source distribution for a package.

:ivar str | None name: The distribution filename, if provided.
:ivar datetime.datetime | None upload_time: The distribution upload time, if known.
:ivar str | None url: The distribution URL, if one is provided.
:ivar str | None path: The distribution path, if one is provided.
:ivar int | None size: The distribution size in bytes, if known.
:ivar Mapping[str, str] hashes: Hashes for the distribution.
"""

name: str | None = None
upload_time: datetime | None = None
url: str | None = None
Expand Down Expand Up @@ -418,6 +461,16 @@ def filename(self) -> str:

@dataclass(frozen=True, kw_only=True, slots=True)
class PackageWheel:
"""A wheel distribution for a package.

:ivar str | None name: The distribution filename, if provided.
:ivar datetime.datetime | None upload_time: The distribution upload time, if known.
:ivar str | None url: The distribution URL, if one is provided.
:ivar str | None path: The distribution path, if one is provided.
:ivar int | None size: The distribution size in bytes, if known.
:ivar Mapping[str, str] hashes: Hashes for the distribution.
"""

name: str | None = None
upload_time: datetime | None = None
url: str | None = None
Expand Down Expand Up @@ -449,6 +502,26 @@ def filename(self) -> str:

@dataclass(frozen=True, kw_only=True, slots=True)
class Package:
"""A package entry in a pylock file.

A package has either distribution files or one direct source (VCS,
directory, or archive).

:ivar NormalizedName name: The normalized package name.
:ivar Version | None version: The package version, if known.
:ivar Marker | None marker: A marker restricting this package, if any.
:ivar SpecifierSet | None requires_python: The supported Python versions.
:ivar Sequence[Mapping[str, Any]] | None dependencies: Package dependencies.
:ivar PackageVcs | None vcs: A VCS source, if selected.
:ivar PackageDirectory | None directory: A directory source, if selected.
:ivar PackageArchive | None archive: An archive source, if selected.
:ivar str | None index: The package index name, if provided.
:ivar PackageSdist | None sdist: A source distribution, if provided.
:ivar Sequence[PackageWheel] | None wheels: Available wheel distributions.
:ivar Sequence[Mapping[str, Any]] | None attestation_identities: Attestations.
:ivar Mapping[str, Any] | None tool: Tool-specific metadata.
"""

name: NormalizedName
version: Version | None = None
marker: Marker | None = None
Expand Down Expand Up @@ -551,7 +624,18 @@ def is_direct(self) -> bool:

@dataclass(frozen=True, kw_only=True, slots=True)
class Pylock:
"""A class representing a pylock file."""
"""Represent a validated pylock file.

:ivar Version lock_version: The pylock specification version.
:ivar Sequence[Marker] | None environments: Supported environments.
:ivar SpecifierSet | None requires_python: The supported Python versions.
:ivar Sequence[NormalizedName] | None extras: Extras provided by the lock.
:ivar Sequence[str] | None dependency_groups: Defined dependency groups.
:ivar Sequence[str] | None default_groups: Groups selected by default.
:ivar str created_by: The tool that created the lock file.
:ivar Sequence[Package] packages: Packages contained in the lock file.
:ivar Mapping[str, Any] | None tool: Tool-specific metadata.
"""

lock_version: Version
environments: Sequence[Marker] | None = None
Expand Down
20 changes: 18 additions & 2 deletions src/packaging/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,18 @@ def __dir__() -> list[str]:

class InvalidRequirement(ValueError):
"""
An invalid requirement was found, users should refer to PEP 508.
Raised when attempting to create a :class:`Requirement` with a string that
does not conform to the specification. Users should refer to PEP 508.

.. versionadded:: 16.1
"""


class Requirement:
"""Parse a requirement.
"""Represent a requirement for a project.

This class abstracts handling the details of a requirement for a project.
Each requirement will be parsed according to the specification.

Parse a given requirement string into its parts, such as name, specifier,
URL, and extras. Raises InvalidRequirement on a badly-formed requirement
Expand Down Expand Up @@ -70,6 +74,18 @@ class Requirement:
Equality and hashing normalize requirement names, extras, and
equivalent specifiers. The string representation still preserves the
parsed name and extras spelling.

:param str requirement_string: The string representation of a requirement.
:raises InvalidRequirement: If the given ``requirement_string`` is not
parseable, then this exception will be raised.
:ivar name: The name of the requirement.
:ivar url: The URL, if any, where to download the requirement from. Can be
``None``.
:ivar extras: A set of extras that the requirement specifies.
:ivar specifier: A :class:`~.SpecifierSet` of the version specified by the
requirement.
:ivar marker: A :class:`~.Marker` of the marker for the requirement. Can be
``None``.
"""

# TODO: Can we test whether something is contained within a requirement?
Expand Down
Loading