Allow explicit typing on Selector using TypeVar with default Any (#932)

This commit is contained in:
Leonardus Chen 2025-10-24 19:37:08 +07:00 committed by GitHub
parent 059f78b27c
commit 18e32521a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 8 deletions

View File

@ -55,7 +55,8 @@ dynamic = ["version"]
dependencies = [ dependencies = [
# typing.Annotated since v3.9 # typing.Annotated since v3.9
# typing.Self and typing.assert_never since v3.11 # 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] [project.optional-dependencies]

View File

@ -4,7 +4,6 @@ from contextlib import AbstractContextManager, AbstractAsyncContextManager
from pathlib import Path from pathlib import Path
from typing import ( from typing import (
Awaitable, Awaitable,
TypeVar,
Generic, Generic,
Type, Type,
Callable as _Callable, Callable as _Callable,
@ -22,6 +21,8 @@ from typing import (
overload, overload,
) )
from typing_extensions import Self as _Self, TypeVar
try: try:
import yaml import yaml
except ImportError: except ImportError:
@ -38,6 +39,7 @@ Injection = Any
ProviderParent = Union["Provider", Any] ProviderParent = Union["Provider", Any]
T = TypeVar("T") T = TypeVar("T")
TT = TypeVar("TT") TT = TypeVar("TT")
T_Any = TypeVar("T_Any", default=Any)
P = TypeVar("P", bound="Provider") P = TypeVar("P", bound="Provider")
BS = TypeVar("BS", bound="BaseSingleton") BS = TypeVar("BS", bound="BaseSingleton")
@ -542,17 +544,17 @@ class Container(Provider[T]):
def parent_name(self) -> Optional[str]: ... def parent_name(self) -> Optional[str]: ...
def assign_parent(self, parent: ProviderParent) -> None: ... def assign_parent(self, parent: ProviderParent) -> None: ...
class Selector(Provider[Any]): class Selector(Provider[T_Any]):
def __init__( def __init__(
self, selector: Optional[_Callable[..., Any]] = None, **providers: Provider self, selector: Optional[_Callable[..., Any]] = None, **providers: Provider
): ... ): ...
def __getattr__(self, name: str) -> Provider: ... def __getattr__(self, name: str) -> Provider[T_Any]: ...
@property @property
def selector(self) -> Optional[_Callable[..., Any]]: ... 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 @property
def providers(self) -> _Dict[str, Provider]: ... def providers(self) -> _Dict[str, Provider[T_Any]]: ...
def set_providers(self, **providers: Provider) -> Selector: ... def set_providers(self, **providers: Provider) -> _Self: ...
class ProvidedInstanceFluentInterface: class ProvidedInstanceFluentInterface:
def __getattr__(self, item: Any) -> AttributeGetter: ... def __getattr__(self, item: Any) -> AttributeGetter: ...

View File

@ -1,4 +1,4 @@
from typing import Any from typing import Any, Callable, Optional, Dict
from dependency_injector import providers from dependency_injector import providers
@ -40,3 +40,36 @@ provider4 = providers.Selector(
async def _async4() -> None: async def _async4() -> None:
var1: Any = await provider4() var1: Any = await provider4()
var2: Any = await provider4.async_() 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