Skip to content

Registry

patiencepilot.solvers.registry

Solver registry for resolving advice providers by name.

SolverFactory

Bases: Protocol

Callable that creates an advice provider.

Source code in src/patiencepilot/solvers/registry.py
13
14
15
16
17
18
class SolverFactory(Protocol):
    """Callable that creates an advice provider."""

    def __call__(self) -> AdviceProvider:
        """Return an advice provider instance."""
        ...

__call__

__call__() -> AdviceProvider

Return an advice provider instance.

Source code in src/patiencepilot/solvers/registry.py
16
17
18
def __call__(self) -> AdviceProvider:
    """Return an advice provider instance."""
    ...

SolverDefinition dataclass

Registered solver metadata and factory.

Source code in src/patiencepilot/solvers/registry.py
21
22
23
24
25
26
27
28
29
30
31
32
@dataclass(frozen=True, slots=True)
class SolverDefinition:
    """Registered solver metadata and factory."""

    name: str
    factory: SolverFactory
    aliases: tuple[str, ...] = ()
    description: str | None = None

    def create(self) -> AdviceProvider:
        """Return a new advice provider instance."""
        return self.factory()

create

create() -> AdviceProvider

Return a new advice provider instance.

Source code in src/patiencepilot/solvers/registry.py
30
31
32
def create(self) -> AdviceProvider:
    """Return a new advice provider instance."""
    return self.factory()

SolverRegistry dataclass

Small immutable registry of supported solvers.

Source code in src/patiencepilot/solvers/registry.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
@dataclass(frozen=True, slots=True)
class SolverRegistry:
    """Small immutable registry of supported solvers."""

    definitions: tuple[SolverDefinition, ...]

    def __post_init__(self) -> None:
        """Validate registry keys."""
        keys: set[str] = set()
        for definition in self.definitions:
            for name in (definition.name, *definition.aliases):
                normalized = _normalize_solver_name(name)
                if normalized in keys:
                    msg = f"duplicate solver registry name: {name!r}"
                    raise InvalidStateError(msg)
                keys.add(normalized)

    @property
    def names(self) -> tuple[str, ...]:
        """Return canonical registered solver names."""
        return tuple(definition.name for definition in self.definitions)

    def register(self, definition: SolverDefinition) -> SolverRegistry:
        """Return a new registry that also contains ``definition``.

        Args:
            definition: Solver definition to add.
        """
        return SolverRegistry((*self.definitions, definition))

    def definition_for(self, name: str) -> SolverDefinition:
        """Return the registered definition for ``name`` or alias.

        Args:
            name: Solver name or alias.

        Raises:
            UnsupportedSolverError: If no solver is registered for ``name``.
        """
        normalized = _normalize_solver_name(name)
        for definition in self.definitions:
            if normalized == _normalize_solver_name(definition.name):
                return definition
            if any(normalized == _normalize_solver_name(alias) for alias in definition.aliases):
                return definition

        msg = f"unsupported solver: {name!r}"
        raise UnsupportedSolverError(msg)

    def create(self, name: str) -> AdviceProvider:
        """Return a new advice provider by solver name.

        Args:
            name: Solver name or alias.
        """
        return self.definition_for(name).create()

names property

names: tuple[str, ...]

Return canonical registered solver names.

__post_init__

__post_init__() -> None

Validate registry keys.

Source code in src/patiencepilot/solvers/registry.py
41
42
43
44
45
46
47
48
49
50
def __post_init__(self) -> None:
    """Validate registry keys."""
    keys: set[str] = set()
    for definition in self.definitions:
        for name in (definition.name, *definition.aliases):
            normalized = _normalize_solver_name(name)
            if normalized in keys:
                msg = f"duplicate solver registry name: {name!r}"
                raise InvalidStateError(msg)
            keys.add(normalized)

register

register(definition: SolverDefinition) -> SolverRegistry

Return a new registry that also contains definition.

Parameters:

Name Type Description Default
definition SolverDefinition

Solver definition to add.

required
Source code in src/patiencepilot/solvers/registry.py
57
58
59
60
61
62
63
def register(self, definition: SolverDefinition) -> SolverRegistry:
    """Return a new registry that also contains ``definition``.

    Args:
        definition: Solver definition to add.
    """
    return SolverRegistry((*self.definitions, definition))

definition_for

definition_for(name: str) -> SolverDefinition

Return the registered definition for name or alias.

Parameters:

Name Type Description Default
name str

Solver name or alias.

required

Raises:

Type Description
UnsupportedSolverError

If no solver is registered for name.

Source code in src/patiencepilot/solvers/registry.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def definition_for(self, name: str) -> SolverDefinition:
    """Return the registered definition for ``name`` or alias.

    Args:
        name: Solver name or alias.

    Raises:
        UnsupportedSolverError: If no solver is registered for ``name``.
    """
    normalized = _normalize_solver_name(name)
    for definition in self.definitions:
        if normalized == _normalize_solver_name(definition.name):
            return definition
        if any(normalized == _normalize_solver_name(alias) for alias in definition.aliases):
            return definition

    msg = f"unsupported solver: {name!r}"
    raise UnsupportedSolverError(msg)

create

create(name: str) -> AdviceProvider

Return a new advice provider by solver name.

Parameters:

Name Type Description Default
name str

Solver name or alias.

required
Source code in src/patiencepilot/solvers/registry.py
84
85
86
87
88
89
90
def create(self, name: str) -> AdviceProvider:
    """Return a new advice provider by solver name.

    Args:
        name: Solver name or alias.
    """
    return self.definition_for(name).create()

resolve_solver

resolve_solver(
    name: str = "dummy",
    *,
    registry: SolverRegistry | None = None,
) -> AdviceProvider

Return an advice provider for a registered solver name.

Parameters:

Name Type Description Default
name str

Solver name or alias. Defaults to "dummy".

'dummy'
registry SolverRegistry | None

Registry to use. Defaults to the package registry.

None
Source code in src/patiencepilot/solvers/registry.py
 93
 94
 95
 96
 97
 98
 99
100
def resolve_solver(name: str = "dummy", *, registry: SolverRegistry | None = None) -> AdviceProvider:
    """Return an advice provider for a registered solver name.

    Args:
        name: Solver name or alias. Defaults to ``"dummy"``.
        registry: Registry to use. Defaults to the package registry.
    """
    return _registry_or_default(registry).create(name)

solver_names

solver_names(
    *, registry: SolverRegistry | None = None
) -> tuple[str, ...]

Return canonical names of registered solvers.

Source code in src/patiencepilot/solvers/registry.py
103
104
105
def solver_names(*, registry: SolverRegistry | None = None) -> tuple[str, ...]:
    """Return canonical names of registered solvers."""
    return _registry_or_default(registry).names