Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ dynamic = ["version"]
dependencies = [
# typing.Annotated since v3.9
# typing.Self and typing.assert_never since v3.11
"typing-extensions; python_version<'3.11'",
# typing.TypeVar default since v3.13
"typing-extensions; python_version<'3.13'",
]

[project.optional-dependencies]
Expand Down
14 changes: 8 additions & 6 deletions src/dependency_injector/providers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ from contextlib import AbstractContextManager, AbstractAsyncContextManager
from pathlib import Path
from typing import (
Awaitable,
TypeVar,
Generic,
Type,
Callable as _Callable,
Expand All @@ -22,6 +21,8 @@ from typing import (
overload,
)

from typing_extensions import Self as _Self, TypeVar

try:
import yaml
except ImportError:
Expand All @@ -38,6 +39,7 @@ Injection = Any
ProviderParent = Union["Provider", Any]
T = TypeVar("T")
TT = TypeVar("TT")
T_Any = TypeVar("T_Any", default=Any)
P = TypeVar("P", bound="Provider")
BS = TypeVar("BS", bound="BaseSingleton")

Expand Down Expand Up @@ -542,17 +544,17 @@ class Container(Provider[T]):
def parent_name(self) -> Optional[str]: ...
def assign_parent(self, parent: ProviderParent) -> None: ...

class Selector(Provider[Any]):
class Selector(Provider[T_Any]):
def __init__(
self, selector: Optional[_Callable[..., Any]] = None, **providers: Provider
): ...
def __getattr__(self, name: str) -> Provider: ...
def __getattr__(self, name: str) -> Provider[T_Any]: ...
@property
def selector(self) -> Optional[_Callable[..., Any]]: ...
def set_selector(self, selector: Optional[_Callable[..., Any]]) -> Selector: ...
def set_selector(self, selector: Optional[_Callable[..., Any]]) -> _Self: ...
@property
def providers(self) -> _Dict[str, Provider]: ...
def set_providers(self, **providers: Provider) -> Selector: ...
def providers(self) -> _Dict[str, Provider[T_Any]]: ...
def set_providers(self, **providers: Provider) -> _Self: ...

class ProvidedInstanceFluentInterface:
def __getattr__(self, item: Any) -> AttributeGetter: ...
Expand Down
35 changes: 34 additions & 1 deletion tests/typing/selector.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any
from typing import Any, Callable, Optional, Dict

from dependency_injector import providers

Expand Down Expand Up @@ -40,3 +40,36 @@
async def _async4() -> None:
var1: Any = await provider4()
var2: Any = await provider4.async_()


# Test 5: to check selector getter and setter
provider5 = providers.Selector(
lambda: "a",
a=providers.Factory(object),
b=providers.Factory(object),
)
selector5: Optional[Callable[..., Any]] = provider5.selector
provider5_after_set_selector: providers.Selector[Any] = provider5.set_selector(lambda: "a")

# Test 6: to check providers getter and setter
provider6 = providers.Selector(
lambda: "a",
a=providers.Factory(object),
b=providers.Factory(object),
)
providers6: Dict[str, providers.Provider[Any]] = provider6.providers
provider6_after_set_providers: providers.Selector[Any] = provider6.set_providers(c=providers.Factory(object))


# Test 7: to check explicit typing: return type, getattr, getter/setter of providers and selectors
provider7 = providers.Selector[bool](lambda: "a", a=providers.Factory(bool), b=providers.Factory(int))
var7: bool = provider7()
attr7: providers.Provider[bool] = provider7.a

selector7: Optional[Callable[..., Any]] = provider7.selector
provider7_after_set_selector: providers.Selector[bool] = provider7.set_selector(lambda: "a")

providers7: Dict[str, providers.Provider[bool]] = provider7.providers
provider7_after_set_providers: providers.Selector[bool] = provider7.set_providers(
c=providers.Factory(str)
) # We don't require Provider of subclass of bool yet since Provider is invariant