Skip to content

Markers

Token

Bases: TokenKeyBase

A typed, named provider key.

Two Token instances are equal iff they share the same name. This makes Token safe to redeclare across modules: Token[str]('db.url') in module A resolves to the same provider as Token[str]('db.url') in module B. The type parameter is phantom — it exists only for the static checker and does not affect equality or hashing.

Example
>>> from depin import Token
>>> Token[str]('db.url') == Token[str]('db.url')
True
>>> Token[str]('db.url') == Token[int]('db.url')
True

Named dataclass

Annotated-metadata marker that selects a provider by key.

Use inside Annotated[...] on a provider parameter when the parameter's type alone does not identify the provider — for example to pull a Token value, or a string-keyed binding, into a constructor. Given db_url = Token[str]('db.url')::

def make_pool(url: Annotated[str, Named(db_url)]) -> Pool: ...

key is the provider key to resolve: a Token or a plain string. A bare Token placed directly in Annotated[...] has the same effect; Named is the explicit form and the only way to reference a string key.

Tag dataclass

Annotated-metadata marker that selects a tagged provider.

When several providers share a key (registered with different tag= values), Tag picks one for a parameter::

def report(store: Annotated[Store, Tag('primary')]) -> Report: ...

name must match the tag given at registration. Pairs with the tag= argument of Container.bind().

injected module-attribute

injected: Never

Parameter default marking a parameter that FrozenContainer.inject fills.

The parameter's annotation carries the key: a class, Annotated[T, Tag(...)], Annotated[T, Named(...)], or T | None for a dependency that may be absent. Because it is a default, a marked parameter follows the non-default parameters or is keyword-only.

provides

provides(abstract: type[object]) -> _ProvidesDecorator

Tag a class with the abstract type it implements.

Decorating @provides(Abstract) records Abstract as the class's provider key, so Container.bind() registers the concrete class under the abstract type without an explicit provides= argument. Useful for binding an implementation against a typing.Protocol or base class.

The decorated class is returned unchanged and keeps its own type, so nothing downstream of the decorator sees a different class.

Parameters:

Name Type Description Default
abstract type[object]

The key to register the decorated class under. Any class, including a Protocol and an abstract base class, or a parameterised generic such as Repo[User], spelled by subscripting its own origin rather than a deprecated typing alias.

required

Raises:

Type Description
InvalidProviderError

abstract is neither a class nor a parameterised generic depin can key by, so it could never serve as the provider key the decorator promises to record. A deprecated typing alias, a union, and a generic whose arguments are not themselves keys each report why in their own terms.

Example
>>> from typing import Protocol
>>> from depin import Container, provides
>>> class Store(Protocol):
...     def get(self) -> str: ...
>>> @provides(Store)
... class MemStore:
...     def get(self) -> str:
...         return 'mem'
>>> di = Container().bind(MemStore).freeze()
>>> di.resolve(Store).get()
'mem'