abstract.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. from __future__ import annotations
  2. import collections
  3. from typing import TYPE_CHECKING, Any, Generic, Iterable, NamedTuple
  4. from ..structs import CT, KT, RT, DirectedGraph
  5. if TYPE_CHECKING:
  6. from ..providers import AbstractProvider
  7. from ..reporters import BaseReporter
  8. from .criterion import Criterion
  9. class Result(NamedTuple, Generic[RT, CT, KT]):
  10. mapping: dict[KT, CT]
  11. graph: DirectedGraph[KT | None]
  12. criteria: dict[KT, Criterion[RT, CT]]
  13. else:
  14. Result = collections.namedtuple("Result", ["mapping", "graph", "criteria"])
  15. class AbstractResolver(Generic[RT, CT, KT]):
  16. """The thing that performs the actual resolution work."""
  17. base_exception = Exception
  18. def __init__(
  19. self,
  20. provider: AbstractProvider[RT, CT, KT],
  21. reporter: BaseReporter[RT, CT, KT],
  22. ) -> None:
  23. self.provider = provider
  24. self.reporter = reporter
  25. def resolve(self, requirements: Iterable[RT], **kwargs: Any) -> Result[RT, CT, KT]:
  26. """Take a collection of constraints, spit out the resolution result.
  27. This returns a representation of the final resolution state, with one
  28. guarenteed attribute ``mapping`` that contains resolved candidates as
  29. values. The keys are their respective identifiers.
  30. :param requirements: A collection of constraints.
  31. :param kwargs: Additional keyword arguments that subclasses may accept.
  32. :raises: ``self.base_exception`` or its subclass.
  33. """
  34. raise NotImplementedError