Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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()