Decorator module
tidi.decorator
Provides the main inject
decorator.
Uses tidi.parameters
to determine which parameters of the wrapped function to
replace.
UNSET = Unset()
module-attribute
Sentinel Unset
object used to indicate a kwarg is not set yet.
Provider
Bases: Generic[T]
, Any
Wrapper class around a function that will be called to provide a dependency
Parameters:
Name | Type | Description | Default |
---|---|---|---|
provider_func |
Callable
|
Callable that will return a given
type (TypeVar |
required |
Examples:
Define a provider as a plain function
Give the provider function into the kwarg marked for injection
>>> @tidi.inject
... def get_hammers(
... toolbox: tidi.Injected[Toolbox] = tidi.Provider(get_big_toolbox)
... ) -> list[Hammer]:
... return [tool for tool in toolbox.tools if isinstance(tool, Hammer)]
Now when you call get_hammers
, Tidi will call get_big_toolbox
and
inject it into the toolbox
kwarg
Or, define a provider as a context manager
>>> @contextlib.contextmanager
... def wear_invisibility_cloak() -> t.Iterator[InvisibilityCloak]:
... cloak = get_cloak()
... cloak.activate()
... try:
... yield cloak
... finally:
... cloak.deactivate()
Give that provider context manager into the kwarg marked for injection
>>> @tidi.inject
... def investigate_crime(
... cloak: tidi.Injected[InvisibilityCloak] = tidi.Provider(wear_invisibility_cloak)
... ) -> Evidence | None:
... enter_crime_scene(cloak)
... return search_crime_scene_for_evidence(cloak)
Now when you call investigate_crime
, Tidi will enter the wear_invisibility_cloak
context manager and inject a the InvisibilityCloak
into the cloak
kwarg
Source code in src/tidi/decorator.py
Unset
inject(registry=None)
A decorator that will replace certain keyword arguments with dependencies
Parameters:
Name | Type | Description | Default |
---|---|---|---|
registry |
Registry | None
|
Provide a |
None
|
Returns:
Type | Description |
---|---|
Callable[[Callable[P, R]], Callable[P, R]]
|
The decorator itself. |
Examples:
Define your own inject decorator if you don't want to use the top level package defined one.
>>> # note: `new_injector` doesn't have a registry, which can be useful
>>> new_injector = tidi.decorator.inject()
Use the decorator just like the main one (tidi.inject
)
>>> @new_injector
>>> def create_db_connection(
... db_string: tidi.Injected = tidi.Provider(get_db_conn_string)
... ) -> db_library.DBConn:
... return db_library.connect(db_string)