Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/dependency_injector/providers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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]): ...
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took the libery to go a bit out-of-scope in this PR because otherwise mypy will complain since it can't infer type for T for string imports (.e.g, providers.Coroutine("_coro"))

tests/typing/coroutine.py:16: error: Need type annotation for "provider2"  [var-annotated]

class DelegatedCoroutine(Coroutine[T]): ...

class AbstractCoroutine(Coroutine[T]):
Expand Down
33 changes: 22 additions & 11 deletions tests/typing/configuration.py
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -33,44 +35,53 @@

# 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
config5_ini = providers.Configuration(
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(
yaml_files=["config.yml", Path("config.yml")],
)
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(
Expand Down
8 changes: 6 additions & 2 deletions tests/typing/container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any
from typing_extensions import assert_type

from dependency_injector import providers

Expand All @@ -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])
9 changes: 6 additions & 3 deletions tests/typing/coroutine.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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])
9 changes: 6 additions & 3 deletions tests/typing/declarative_container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Dict
from typing_extensions import assert_type

from dependency_injector import containers, providers

Expand All @@ -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
Expand Down Expand Up @@ -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):
Expand Down
12 changes: 8 additions & 4 deletions tests/typing/delegate.py
Original file line number Diff line number Diff line change
@@ -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]])
11 changes: 8 additions & 3 deletions tests/typing/dependencies_container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any
from typing_extensions import assert_type

from dependency_injector import providers

Expand All @@ -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)
12 changes: 8 additions & 4 deletions tests/typing/dependency.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Type
from typing_extensions import assert_type

from dependency_injector import providers

Expand All @@ -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)
22 changes: 15 additions & 7 deletions tests/typing/dict.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Dict
from typing_extensions import assert_type

from dependency_injector import providers

Expand All @@ -7,35 +8,41 @@
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
provider4 = providers.Dict(
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
provider5 = providers.Dict(
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
Expand All @@ -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])
5 changes: 4 additions & 1 deletion tests/typing/dynamic_container.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Dict
from typing_extensions import assert_type

from dependency_injector import containers, providers

Expand All @@ -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()