Source code for next.deps.providers

"""Parameter-provider contracts and the auto-registry ABC.

`ParameterProvider` is the minimal Protocol consumed by
`DependencyResolver`. `RegisteredParameterProvider` is the ABC used by
built-in providers that ship with the framework. Subclasses of the ABC
join the module-level `_registry` through `__init_subclass__`, which
lets the resolver instantiate them on first use without importing
them explicitly. The resolver consults providers in ascending
`priority` order, so a lower `priority` value is checked first.
`ProviderRegistry` is a lightweight list-style helper kept around for
tests and future external consumers.
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, ClassVar, Protocol, runtime_checkable

from .signals import provider_registered


if TYPE_CHECKING:
    import inspect
    from collections.abc import Iterator

    from .context import ResolutionContext
    from .resolver import DependencyResolver


[docs] @runtime_checkable class ParameterProvider(Protocol): """Minimal protocol consumed by `DependencyResolver`."""
[docs] def can_handle(self, param: inspect.Parameter, context: ResolutionContext) -> bool: """Return True when this provider owns the parameter.""" raise NotImplementedError
[docs] def resolve(self, param: inspect.Parameter, context: ResolutionContext) -> object: """Return the resolved value for the parameter.""" raise NotImplementedError
[docs] class RegisteredParameterProvider(ABC): """Auto-registered base used by built-in providers shipped with the framework.""" resolver: ClassVar[DependencyResolver] _registry: ClassVar[list[type[RegisteredParameterProvider]]] = [] priority: ClassVar[int] = 100
[docs] def __init_subclass__(cls, **kwargs: object) -> None: """Track concrete subclasses for lazy instantiation by the resolver.""" super().__init_subclass__(**kwargs) RegisteredParameterProvider._registry.append(cls) provider_registered.send(sender=cls)
[docs] @abstractmethod def can_handle(self, param: inspect.Parameter, context: ResolutionContext) -> bool: """Return True when this provider owns the parameter."""
[docs] @abstractmethod def resolve(self, param: inspect.Parameter, context: ResolutionContext) -> object: """Return the resolved value for the parameter."""
class ProviderRegistry: """Explicit list-style registry for parameter providers.""" def __init__(self) -> None: """Initialise an empty registry.""" self._providers: list[ParameterProvider] = [] def register(self, provider: ParameterProvider) -> None: """Append a provider to the registry.""" self._providers.append(provider) def get_providers(self) -> tuple[ParameterProvider, ...]: """Return a frozen snapshot of registered providers.""" return tuple(self._providers) def clear(self) -> None: """Drop every registered provider.""" self._providers.clear() def __len__(self) -> int: """Return the number of registered providers.""" return len(self._providers) def __iter__(self) -> Iterator[ParameterProvider]: """Iterate registered providers in registration order.""" return iter(self._providers)