criterion.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. from __future__ import annotations
  2. from typing import Collection, Generic, Iterable, Iterator
  3. from ..structs import CT, RT, RequirementInformation
  4. class Criterion(Generic[RT, CT]):
  5. """Representation of possible resolution results of a package.
  6. This holds three attributes:
  7. * `information` is a collection of `RequirementInformation` pairs.
  8. Each pair is a requirement contributing to this criterion, and the
  9. candidate that provides the requirement.
  10. * `incompatibilities` is a collection of all known not-to-work candidates
  11. to exclude from consideration.
  12. * `candidates` is a collection containing all possible candidates deducted
  13. from the union of contributing requirements and known incompatibilities.
  14. It should never be empty, except when the criterion is an attribute of a
  15. raised `RequirementsConflicted` (in which case it is always empty).
  16. .. note::
  17. This class is intended to be externally immutable. **Do not** mutate
  18. any of its attribute containers.
  19. """
  20. def __init__(
  21. self,
  22. candidates: Iterable[CT],
  23. information: Collection[RequirementInformation[RT, CT]],
  24. incompatibilities: Collection[CT],
  25. ) -> None:
  26. self.candidates = candidates
  27. self.information = information
  28. self.incompatibilities = incompatibilities
  29. def __repr__(self) -> str:
  30. requirements = ", ".join(
  31. f"({req!r}, via={parent!r})" for req, parent in self.information
  32. )
  33. return f"Criterion({requirements})"
  34. def iter_requirement(self) -> Iterator[RT]:
  35. return (i.requirement for i in self.information)
  36. def iter_parent(self) -> Iterator[CT | None]:
  37. return (i.parent for i in self.information)