diff --git a/src/dependency_injector/providers.pyi b/src/dependency_injector/providers.pyi index 8ba2e98d..29248d3e 100644 --- a/src/dependency_injector/providers.pyi +++ b/src/dependency_injector/providers.pyi @@ -197,7 +197,7 @@ class AbstractCallable(Callable[T]): class CallableDelegate(Delegate): def __init__(self, callable: Callable) -> None: ... -class Coroutine(Callable[T]): ... +class Coroutine(Callable[T_Any]): ... class DelegatedCoroutine(Coroutine[T]): ... class AbstractCoroutine(Coroutine[T]): diff --git a/tests/typing/configuration.py b/tests/typing/configuration.py index fd9a1d18..d9e78247 100644 --- a/tests/typing/configuration.py +++ b/tests/typing/configuration.py @@ -1,13 +1,15 @@ from pathlib import Path from typing import Any, Dict +from typing_extensions import assert_type from pydantic_settings import BaseSettings as PydanticSettings from dependency_injector import providers # Test 1: to check the getattr -config1: providers.Configuration = providers.Configuration() -provider1: providers.Provider[Dict[str, Any]] = providers.Factory(dict, a=config1.a) +config1 = providers.Configuration() +provider1 = providers.Factory(dict[str, Any], a=config1.a) +assert_type(provider1, providers.Factory[Dict[str, Any]]) # Test 2: to check the from_*() method config2 = providers.Configuration() @@ -33,13 +35,19 @@ # Test 3: to check as_*() methods config3 = providers.Configuration() -int3: providers.Callable[int] = config3.option.as_int() -float3: providers.Callable[float] = config3.option.as_float() -int3_custom: providers.Callable[int] = config3.option.as_(int) +int3 = config3.option.as_int() +float3 = config3.option.as_float() +int3_custom = config3.option.as_(int) + +assert_type(int3, providers.TypedConfigurationOption[int]) +assert_type(float3, providers.TypedConfigurationOption[float]) +assert_type(int3_custom, providers.TypedConfigurationOption[int]) # Test 4: to check required() method config4 = providers.Configuration() -option4: providers.ConfigurationOption = config4.option.required() +option4 = config4.option.required() +assert_type(option4, providers.ConfigurationOption) + # Test 5: to check get/set config files' methods and init arguments # Test 5: ini @@ -47,7 +55,8 @@ ini_files=["config.ini", Path("config.ini")], ) config5_ini.set_ini_files(["config.ini", Path("config.ini")]) -config5_ini_files: list[str | Path] = config5_ini.get_ini_files() +config5_ini_files = config5_ini.get_ini_files() +assert_type(config5_ini_files, list[str | Path]) # Test 5: yaml config5_yaml = providers.Configuration( @@ -55,22 +64,24 @@ ) config5_yaml.set_yaml_files(["config.yml", Path("config.yml")]) config5_yaml_files: list[str | Path] = config5_yaml.get_yaml_files() +assert_type(config5_yaml_files, list[str | Path]) # Test 5: json config5_json = providers.Configuration( json_files=["config.json", Path("config.json")], ) config5_json.set_json_files(["config.json", Path("config.json")]) -config5_json_files: list[str | Path] = config5_json.get_json_files() +config5_json_files = config5_json.get_json_files() +assert_type(config5_json_files, list[str | Path]) # Test 5: pydantic config5_pydantic = providers.Configuration( pydantic_settings=[PydanticSettings()], ) config5_pydantic.set_pydantic_settings([PydanticSettings()]) -config5_pydantic_settings: list[PydanticSettings] = ( - config5_pydantic.get_pydantic_settings() -) + +# NOTE: Using assignment since PydanticSettings is context-sensitive: conditional on whether pydantic is installed +config5_pydantic_settings: list[PydanticSettings] = (config5_pydantic.get_pydantic_settings()) # Test 6: to check init arguments config6 = providers.Configuration( diff --git a/tests/typing/container.py b/tests/typing/container.py index 1a170b55..99cd6575 100644 --- a/tests/typing/container.py +++ b/tests/typing/container.py @@ -1,4 +1,5 @@ from typing import Any +from typing_extensions import assert_type from dependency_injector import providers @@ -8,8 +9,11 @@ class Container: ... # Test 1: to check the return type provider1 = providers.Container(Container) -var1: Container = provider1() +var1 = provider1() +assert_type(var1, Container) + # Test 2: to check the getattr provider2 = providers.Container(Container) -attr: providers.Provider[Any] = provider2.attr +attr = provider2.attr +assert_type(attr, providers.Provider[Any]) diff --git a/tests/typing/coroutine.py b/tests/typing/coroutine.py index e6234077..190d771a 100644 --- a/tests/typing/coroutine.py +++ b/tests/typing/coroutine.py @@ -1,4 +1,5 @@ -from typing import Awaitable, Coroutine +from typing import Awaitable, Coroutine, Any +from typing_extensions import assert_type from dependency_injector import providers @@ -8,8 +9,10 @@ async def _coro() -> None: ... # Test 1: to check the return type provider1 = providers.Coroutine(_coro) -var1: Awaitable[None] = provider1() +var1 = provider1() +assert_type(var1, Coroutine[Any, Any, None]) # type: ignore[unused-coroutine] # Test 2: to check string imports -provider2: providers.Coroutine[None] = providers.Coroutine("_coro") +provider2 = providers.Coroutine("_coro") provider2.set_provides("_coro") +assert_type(provider2, providers.Coroutine[Any]) diff --git a/tests/typing/declarative_container.py b/tests/typing/declarative_container.py index 5cb4c780..cec332f1 100644 --- a/tests/typing/declarative_container.py +++ b/tests/typing/declarative_container.py @@ -1,4 +1,5 @@ from typing import Any, Dict +from typing_extensions import assert_type from dependency_injector import containers, providers @@ -8,10 +9,12 @@ class Container1(containers.DeclarativeContainer): provider = providers.Factory(int) +# NOTE: Using assignment to check base class instead of exact type container1 = Container1() container1_type: containers.Container = Container1() provider1: providers.Provider[int] = container1.provider -val1: int = container1.provider(3) +val1 = container1.provider(3) +assert_type(val1, int) # Test 2: to check @override decorator @@ -46,8 +49,8 @@ class Container5(containers.DeclarativeContainer): provider = providers.Factory(int) -dependencies: Dict[str, providers.Provider[Any]] = Container5.dependencies - +dependencies = Container5.dependencies +assert_type(dependencies, Dict[str, providers.Provider[Any]]) # Test 6: to check base class class Container6(containers.DeclarativeContainer): diff --git a/tests/typing/delegate.py b/tests/typing/delegate.py index 01b0525e..6294a0ed 100644 --- a/tests/typing/delegate.py +++ b/tests/typing/delegate.py @@ -1,20 +1,24 @@ from typing import Any, Optional +from typing_extensions import assert_type from dependency_injector import providers # Test 1: to check the return type provider1 = providers.Delegate(providers.Provider()) -var1: providers.Provider[Any] = provider1() +var1 = provider1() +assert_type(var1, providers.Provider[Any]) # Test 2: to check the return type with await provider2 = providers.Delegate(providers.Provider()) async def _async2() -> None: - var1: providers.Provider[Any] = await provider2() # type: ignore - var2: providers.Provider[Any] = await provider2.async_() + var1 = await provider2() # type: ignore + var2 = await provider2.async_() + assert_type(var2, providers.Provider[Any]) # Test 3: to check class type from provider provider3 = providers.Delegate(providers.Provider()) -provided_provides: Optional[providers.Provider[Any]] = provider3.provides +provided_provides = provider3.provides +assert_type(provided_provides, Optional[providers.Provider[Any]]) diff --git a/tests/typing/dependencies_container.py b/tests/typing/dependencies_container.py index 614c445e..a2184903 100644 --- a/tests/typing/dependencies_container.py +++ b/tests/typing/dependencies_container.py @@ -1,4 +1,5 @@ from typing import Any +from typing_extensions import assert_type from dependency_injector import providers @@ -7,6 +8,10 @@ a=providers.Provider(), b=providers.Provider(), ) -a1: providers.Provider[Any] = provider1.a -b1: providers.Provider[Any] = provider1.b -c1: providers.ProvidedInstance = provider1.c.provided +a1 = provider1.a +b1 = provider1.b +c1 = provider1.c.provided + +assert_type(a1, providers.Provider[Any]) +assert_type(b1, providers.Provider[Any]) +assert_type(c1, providers.ProvidedInstance) diff --git a/tests/typing/dependency.py b/tests/typing/dependency.py index 10711f93..963df8f0 100644 --- a/tests/typing/dependency.py +++ b/tests/typing/dependency.py @@ -1,4 +1,5 @@ from typing import Any, Type +from typing_extensions import assert_type from dependency_injector import providers @@ -14,16 +15,19 @@ def __init__(self, *a: Any, **kw: Any) -> None: ... # Test 1: to check the return type provider1 = providers.Dependency(instance_of=Animal) provider1.override(providers.Factory(Cat)) -var1: Animal = provider1() +var1 = provider1() +assert_type(var1, Animal) # Test 2: to check the return type provider2 = providers.Dependency(instance_of=Animal) -var2: Type[Animal] = provider2.instance_of +var2 = provider2.instance_of +assert_type(var2, Type[Animal]) # Test 3: to check the return type with await provider3 = providers.Dependency(instance_of=Animal) async def _async3() -> None: - var1: Animal = await provider3() # type: ignore - var2: Animal = await provider3.async_() + var1 = await provider3() # type: ignore + var2 = await provider3.async_() + assert_type(var2, Animal) diff --git a/tests/typing/dict.py b/tests/typing/dict.py index 2a6b0044..30bfa57c 100644 --- a/tests/typing/dict.py +++ b/tests/typing/dict.py @@ -1,4 +1,5 @@ from typing import Any, Dict +from typing_extensions import assert_type from dependency_injector import providers @@ -7,19 +8,23 @@ a1=providers.Factory(object), a2=providers.Factory(object), ) -var1: Dict[Any, Any] = provider1() +var1 = provider1() +assert_type(var1, Dict[Any, Any]) + # Test 2: to check init with non-string keys provider2 = providers.Dict({object(): providers.Factory(object)}) -var2: Dict[Any, Any] = provider2() +var2 = provider2() +assert_type(var2, Dict[Any, Any]) # Test 3: to check init with non-string keys provider3 = providers.Dict( {object(): providers.Factory(object)}, a2=providers.Factory(object) ) -var3: Dict[Any, Any] = provider3() +var3 = provider3() +assert_type(var3, Dict[Any, Any]) # Test 4: to check the .args attributes @@ -27,7 +32,8 @@ a1=providers.Factory(object), a2=providers.Factory(object), ) -args4: Dict[Any, Any] = provider4.kwargs +args = provider4.kwargs +assert_type(args, Dict[Any, Any]) # Test 5: to check the provided instance interface @@ -35,7 +41,8 @@ a1=providers.Factory(object), a2=providers.Factory(object), ) -provided5: dict[Any, Any] = provider5.provided() +provided5 = provider5.provided() +assert_type(provided5, Any) # Test 6: to check the return type with await @@ -46,5 +53,6 @@ async def _async3() -> None: - var1: Dict[Any, Any] = await provider6() # type: ignore - var2: Dict[Any, Any] = await provider6.async_() + var1 = await provider6() # type: ignore + var2 = await provider6.async_() + assert_type(var2, Dict[Any, Any]) diff --git a/tests/typing/dynamic_container.py b/tests/typing/dynamic_container.py index b88da6bd..9febded3 100644 --- a/tests/typing/dynamic_container.py +++ b/tests/typing/dynamic_container.py @@ -1,4 +1,5 @@ from typing import Any, Dict +from typing_extensions import assert_type from dependency_injector import containers, providers @@ -22,7 +23,9 @@ # Test 5: to check .dependencies attribute container5 = containers.DynamicContainer() -dependencies: Dict[str, providers.Provider[Any]] = container5.dependencies +dependencies = container5.dependencies +assert_type(dependencies, Dict[str, providers.Provider[Any]]) # Test 6: to check base class +# NOTE: Using assignment to check base class instead of exact type container6: containers.Container = containers.DynamicContainer()