From 99489afa3fd9ddf397f363ed5f7213dbc6a19c21 Mon Sep 17 00:00:00 2001 From: ZipFile Date: Wed, 28 May 2025 20:35:04 +0000 Subject: [PATCH 1/6] Strip debug symbols when building wheels --- .github/workflows/publishing.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publishing.yml b/.github/workflows/publishing.yml index 893536a4..af4e1cd1 100644 --- a/.github/workflows/publishing.yml +++ b/.github/workflows/publishing.yml @@ -66,6 +66,7 @@ jobs: CIBW_ENVIRONMENT: >- PIP_CONFIG_SETTINGS="build_ext=-j4" DEPENDENCY_INJECTOR_LIMITED_API="1" + CFLAGS="-g0" steps: - uses: actions/checkout@v3 - name: Build wheels From b9df88eea7730e25445889e96104aaf6abb64922 Mon Sep 17 00:00:00 2001 From: ZipFile Date: Fri, 30 May 2025 19:28:49 +0000 Subject: [PATCH 2/6] Fix typing for wiring marker --- src/dependency_injector/containers.pyi | 2 +- src/dependency_injector/wiring.py | 97 +++++++++++++++++--------- tests/typing/wiring.py | 36 ++++++++++ 3 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 tests/typing/wiring.py diff --git a/src/dependency_injector/containers.pyi b/src/dependency_injector/containers.pyi index 4b40fbba..ec41ea8e 100644 --- a/src/dependency_injector/containers.pyi +++ b/src/dependency_injector/containers.pyi @@ -41,7 +41,7 @@ class WiringConfiguration: class Container: provider_type: Type[Provider] = Provider providers: Dict[str, Provider] - dependencies: Dict[str, Provider] + dependencies: Dict[str, Provider[Any]] overridden: Tuple[Provider] wiring_config: WiringConfiguration auto_load_config: bool = True diff --git a/src/dependency_injector/wiring.py b/src/dependency_injector/wiring.py index 6829d53b..b8534ee5 100644 --- a/src/dependency_injector/wiring.py +++ b/src/dependency_injector/wiring.py @@ -8,13 +8,14 @@ import pkgutil import sys from types import ModuleType from typing import ( + TYPE_CHECKING, Any, Callable, Dict, - Generic, Iterable, Iterator, Optional, + Protocol, Set, Tuple, Type, @@ -23,6 +24,7 @@ from typing import ( cast, ) +from typing_extensions import Self # Hotfix, see: https://github.com/ets-labs/python-dependency-injector/issues/362 if sys.version_info >= (3, 9): @@ -66,7 +68,6 @@ except ImportError: from . import providers - __all__ = ( "wire", "unwire", @@ -89,7 +90,11 @@ __all__ = ( T = TypeVar("T") F = TypeVar("F", bound=Callable[..., Any]) -Container = Any + +if TYPE_CHECKING: + from .containers import Container +else: + Container = Any class PatchedRegistry: @@ -777,15 +782,15 @@ class RequiredModifier(Modifier): def __init__(self) -> None: self.type_modifier = None - def as_int(self) -> "RequiredModifier": + def as_int(self) -> Self: self.type_modifier = TypeModifier(int) return self - def as_float(self) -> "RequiredModifier": + def as_float(self) -> Self: self.type_modifier = TypeModifier(float) return self - def as_(self, type_: Type) -> "RequiredModifier": + def as_(self, type_: Type) -> Self: self.type_modifier = TypeModifier(type_) return self @@ -833,15 +838,15 @@ class ProvidedInstance(Modifier): def __init__(self) -> None: self.segments = [] - def __getattr__(self, item): + def __getattr__(self, item: str) -> Self: self.segments.append((self.TYPE_ATTRIBUTE, item)) return self - def __getitem__(self, item): + def __getitem__(self, item) -> Self: self.segments.append((self.TYPE_ITEM, item)) return self - def call(self): + def call(self) -> Self: self.segments.append((self.TYPE_CALL, None)) return self @@ -866,36 +871,56 @@ def provided() -> ProvidedInstance: return ProvidedInstance() -class _Marker(Generic[T]): - - __IS_MARKER__ = True - - def __init__( - self, - provider: Union[providers.Provider, Container, str], - modifier: Optional[Modifier] = None, - ) -> None: - if _is_declarative_container(provider): - provider = provider.__self__ - self.provider = provider - self.modifier = modifier - - def __class_getitem__(cls, item) -> T: - if isinstance(item, tuple): - return cls(*item) - return cls(item) - - def __call__(self) -> T: - return self +MarkerItem = Union[ + str, + providers.Provider[Any], + Tuple[str, TypeModifier], + Type[Container], + "_Marker", +] -class Provide(_Marker): ... +if TYPE_CHECKING: + class _Marker(Protocol): + __IS_MARKER__: bool -class Provider(_Marker): ... + def __call__(self) -> Self: ... + def __getattr__(self, item: str) -> Self: ... + def __getitem__(self, item: Any) -> Any: ... + Provide: _Marker + Provider: _Marker + Closing: _Marker +else: -class Closing(_Marker): ... + class _Marker: + + __IS_MARKER__ = True + + def __init__( + self, + provider: Union[providers.Provider, Container, str], + modifier: Optional[Modifier] = None, + ) -> None: + if _is_declarative_container(provider): + provider = provider.__self__ + self.provider = provider + self.modifier = modifier + + def __class_getitem__(cls, item: MarkerItem) -> Self: + if isinstance(item, tuple): + return cls(*item) + return cls(item) + + def __call__(self) -> Self: + return self + + class Provide(_Marker): ... + + class Provider(_Marker): ... + + class Closing(_Marker): ... class AutoLoader: @@ -998,8 +1023,8 @@ _inspect_filter = InspectFilter() _loader = AutoLoader() # Optimizations -from ._cwiring import _sync_inject # noqa from ._cwiring import _async_inject # noqa +from ._cwiring import _sync_inject # noqa # Wiring uses the following Python wrapper because there is @@ -1028,13 +1053,17 @@ def _get_sync_patched(fn: F, patched: PatchedCallable) -> F: patched.injections, patched.closing, ) + return cast(F, _patched) if sys.version_info >= (3, 10): + def _get_annotations(obj: Any) -> Dict[str, Any]: return inspect.get_annotations(obj) + else: + def _get_annotations(obj: Any) -> Dict[str, Any]: return getattr(obj, "__annotations__", {}) diff --git a/tests/typing/wiring.py b/tests/typing/wiring.py new file mode 100644 index 00000000..078fe3cf --- /dev/null +++ b/tests/typing/wiring.py @@ -0,0 +1,36 @@ +from typing import Iterator + +from typing_extensions import Annotated + +from dependency_injector.containers import DeclarativeContainer +from dependency_injector.providers import Object, Resource +from dependency_injector.wiring import Closing, Provide, required + + +def _resource() -> Iterator[int]: + yield 1 + + +class Container(DeclarativeContainer): + value = Object(1) + res = Resource(_resource) + + +def default_by_ref(value: int = Provide[Container.value]) -> None: ... +def default_by_string(value: int = Provide["value"]) -> None: ... +def default_by_string_with_modifier( + value: int = Provide["value", required().as_int()] +) -> None: ... +def default_container(container: Container = Provide[Container]) -> None: ... +def default_with_closing(value: int = Closing[Provide[Container.res]]) -> None: ... +def annotated_by_ref(value: Annotated[int, Provide[Container.value]]) -> None: ... +def annotated_by_string(value: Annotated[int, Provide["value"]]) -> None: ... +def annotated_by_string_with_modifier( + value: Annotated[int, Provide["value", required().as_int()]], +) -> None: ... +def annotated_container( + container: Annotated[Container, Provide[Container]], +) -> None: ... +def annotated_with_closing( + value: Annotated[int, Closing[Provide[Container.res]]], +) -> None: ... From 1271d0fa7956e694c99370120dde4da7930ebcf3 Mon Sep 17 00:00:00 2001 From: ZipFile Date: Fri, 30 May 2025 19:29:11 +0000 Subject: [PATCH 3/6] Add type info for _cwiring module --- src/dependency_injector/_cwiring.pyi | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/dependency_injector/_cwiring.pyi diff --git a/src/dependency_injector/_cwiring.pyi b/src/dependency_injector/_cwiring.pyi new file mode 100644 index 00000000..e7ff12f4 --- /dev/null +++ b/src/dependency_injector/_cwiring.pyi @@ -0,0 +1,23 @@ +from typing import Any, Awaitable, Callable, Dict, Tuple, TypeVar + +from .providers import Provider + +T = TypeVar("T") + +def _sync_inject( + fn: Callable[..., T], + args: Tuple[Any, ...], + kwargs: Dict[str, Any], + injections: Dict[str, Provider[Any]], + closings: Dict[str, Provider[Any]], + /, +) -> T: ... +async def _async_inject( + fn: Callable[..., Awaitable[T]], + args: Tuple[Any, ...], + kwargs: Dict[str, Any], + injections: Dict[str, Provider[Any]], + closings: Dict[str, Provider[Any]], + /, +) -> T: ... +def _isawaitable(instance: Any) -> bool: ... From 7fcf1ac7ad5d9160edde1960e599d2ecd0f7c54c Mon Sep 17 00:00:00 2001 From: ZipFile Date: Fri, 30 May 2025 19:31:44 +0000 Subject: [PATCH 4/6] Make `mypy --strict tests/typing` passable --- tests/typing/aggregate.py | 18 ++++++----- tests/typing/callable.py | 10 +++--- tests/typing/configuration.py | 10 +++--- tests/typing/container.py | 7 +++-- tests/typing/coroutine.py | 8 ++--- tests/typing/declarative_container.py | 14 ++++----- tests/typing/delegate.py | 13 +++++--- tests/typing/dependencies_container.py | 7 +++-- tests/typing/dependency.py | 9 +++--- tests/typing/dict.py | 7 +++-- tests/typing/dynamic_container.py | 5 ++- tests/typing/factory.py | 42 +++++++++++++++++--------- tests/typing/list.py | 5 +-- tests/typing/object.py | 6 ++-- tests/typing/provider.py | 5 +-- tests/typing/resource.py | 23 +++++++++----- tests/typing/selector.py | 7 +++-- tests/typing/singleton.py | 12 +++++--- tox.ini | 2 +- 19 files changed, 127 insertions(+), 83 deletions(-) diff --git a/tests/typing/aggregate.py b/tests/typing/aggregate.py index 993634f7..1f134cb0 100644 --- a/tests/typing/aggregate.py +++ b/tests/typing/aggregate.py @@ -1,12 +1,10 @@ from dependency_injector import providers -class Animal: - ... +class Animal: ... -class Cat(Animal): - ... +class Cat(Animal): ... # Test 1: to check Aggregate provider @@ -20,13 +18,19 @@ val1: str = provider1("a") provider1_set_non_string_keys: providers.Aggregate[str] = providers.Aggregate() provider1_set_non_string_keys.set_providers({Cat: providers.Object("str")}) -provider_set_non_string_1: providers.Provider[str] = provider1_set_non_string_keys.providers[Cat] +provider_set_non_string_1: providers.Provider[str] = ( + provider1_set_non_string_keys.providers[Cat] +) provider1_new_non_string_keys: providers.Aggregate[str] = providers.Aggregate( {Cat: providers.Object("str")}, ) -factory_new_non_string_1: providers.Provider[str] = provider1_new_non_string_keys.providers[Cat] +factory_new_non_string_1: providers.Provider[str] = ( + provider1_new_non_string_keys.providers[Cat] +) provider1_no_explicit_typing = providers.Aggregate(a=providers.Object("str")) -provider1_no_explicit_typing_factory: providers.Provider[str] = provider1_no_explicit_typing.providers["a"] +provider1_no_explicit_typing_factory: providers.Provider[str] = ( + provider1_no_explicit_typing.providers["a"] +) provider1_no_explicit_typing_object: str = provider1_no_explicit_typing("a") diff --git a/tests/typing/callable.py b/tests/typing/callable.py index 09a5a3f8..8d345d3b 100644 --- a/tests/typing/callable.py +++ b/tests/typing/callable.py @@ -1,10 +1,9 @@ -from typing import Callable, Optional, Tuple, Any, Dict, Type +from typing import Any, Callable, Dict, Optional, Tuple, Type from dependency_injector import providers -class Animal: - ... +class Animal: ... class Cat(Animal): @@ -53,10 +52,13 @@ provider8 = providers.CallableDelegate(providers.Callable(lambda: None)) # Test 9: to check the return type with await provider9 = providers.Callable(Cat) + + async def _async9() -> None: animal1: Animal = await provider9(1, 2, 3, b="1", c=2, e=0.0) # type: ignore animal2: Animal = await provider9.async_(1, 2, 3, b="1", c=2, e=0.0) + # Test 10: to check the .provides provider10 = providers.Callable(Cat) provides10: Optional[Callable[..., Cat]] = provider10.provides @@ -68,5 +70,5 @@ provides11: Optional[Callable[..., Animal]] = provider11.provides assert provides11 is Cat # Test 12: to check string imports -provider12: providers.Callable[dict] = providers.Callable("builtins.dict") +provider12: providers.Callable[Dict[Any, Any]] = providers.Callable("builtins.dict") provider12.set_provides("builtins.dict") diff --git a/tests/typing/configuration.py b/tests/typing/configuration.py index 832281d3..fd9a1d18 100644 --- a/tests/typing/configuration.py +++ b/tests/typing/configuration.py @@ -1,13 +1,13 @@ from pathlib import Path -from typing import Any +from typing import Any, Dict -from dependency_injector import providers 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] = providers.Factory(dict, a=config1.a) +provider1: providers.Provider[Dict[str, Any]] = providers.Factory(dict, a=config1.a) # Test 2: to check the from_*() method config2 = providers.Configuration() @@ -68,7 +68,9 @@ config5_pydantic = providers.Configuration( pydantic_settings=[PydanticSettings()], ) config5_pydantic.set_pydantic_settings([PydanticSettings()]) -config5_pydantic_settings: list[PydanticSettings] = config5_pydantic.get_pydantic_settings() +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 768f1d3f..1a170b55 100644 --- a/tests/typing/container.py +++ b/tests/typing/container.py @@ -1,8 +1,9 @@ +from typing import Any + from dependency_injector import providers -class Container: - ... +class Container: ... # Test 1: to check the return type @@ -11,4 +12,4 @@ var1: Container = provider1() # Test 2: to check the getattr provider2 = providers.Container(Container) -attr: providers.Provider = provider2.attr +attr: providers.Provider[Any] = provider2.attr diff --git a/tests/typing/coroutine.py b/tests/typing/coroutine.py index 40c8e530..e6234077 100644 --- a/tests/typing/coroutine.py +++ b/tests/typing/coroutine.py @@ -1,14 +1,14 @@ -from typing import Coroutine +from typing import Awaitable, Coroutine from dependency_injector import providers -async def _coro() -> None: - ... +async def _coro() -> None: ... + # Test 1: to check the return type provider1 = providers.Coroutine(_coro) -var1: Coroutine = provider1() +var1: Awaitable[None] = provider1() # Test 2: to check string imports provider2: providers.Coroutine[None] = providers.Coroutine("_coro") diff --git a/tests/typing/declarative_container.py b/tests/typing/declarative_container.py index 92d06c92..5cb4c780 100644 --- a/tests/typing/declarative_container.py +++ b/tests/typing/declarative_container.py @@ -1,4 +1,4 @@ -from typing import Dict +from typing import Any, Dict from dependency_injector import containers, providers @@ -10,7 +10,7 @@ class Container1(containers.DeclarativeContainer): container1 = Container1() container1_type: containers.Container = Container1() -provider1: providers.Provider = container1.provider +provider1: providers.Provider[int] = container1.provider val1: int = container1.provider(3) @@ -20,8 +20,7 @@ class Container21(containers.DeclarativeContainer): @containers.override(Container21) -class Container22(containers.DeclarativeContainer): - ... +class Container22(containers.DeclarativeContainer): ... # Test 3: to check @copy decorator @@ -30,14 +29,14 @@ class Container31(containers.DeclarativeContainer): @containers.copy(Container31) -class Container32(containers.DeclarativeContainer): - ... +class Container32(containers.DeclarativeContainer): ... # Test 4: to override() class Container4(containers.DeclarativeContainer): provider = providers.Factory(int) + container4 = Container4() container4.override(Container4()) @@ -47,7 +46,7 @@ class Container5(containers.DeclarativeContainer): provider = providers.Factory(int) -dependencies: Dict[str, providers.Provider] = Container5.dependencies +dependencies: Dict[str, providers.Provider[Any]] = Container5.dependencies # Test 6: to check base class @@ -62,6 +61,7 @@ container6: containers.Container = Container6() class Container7(containers.DeclarativeContainer): provider = providers.Factory(str) + container7 = Container7() container7.override_providers(provider="new_value") with container7.override_providers(a=providers.Provider()): diff --git a/tests/typing/delegate.py b/tests/typing/delegate.py index b4fb7d33..01b0525e 100644 --- a/tests/typing/delegate.py +++ b/tests/typing/delegate.py @@ -1,17 +1,20 @@ -from typing import Optional +from typing import Any, Optional from dependency_injector import providers # Test 1: to check the return type provider1 = providers.Delegate(providers.Provider()) -var1: providers.Provider = provider1() +var1: providers.Provider[Any] = provider1() # Test 2: to check the return type with await provider2 = providers.Delegate(providers.Provider()) + + async def _async2() -> None: - var1: providers.Provider = await provider2() # type: ignore - var2: providers.Provider = await provider2.async_() + var1: providers.Provider[Any] = await provider2() # type: ignore + var2: providers.Provider[Any] = await provider2.async_() + # Test 3: to check class type from provider provider3 = providers.Delegate(providers.Provider()) -provided_provides: Optional[providers.Provider] = provider3.provides +provided_provides: Optional[providers.Provider[Any]] = provider3.provides diff --git a/tests/typing/dependencies_container.py b/tests/typing/dependencies_container.py index 7cac45d7..614c445e 100644 --- a/tests/typing/dependencies_container.py +++ b/tests/typing/dependencies_container.py @@ -1,11 +1,12 @@ -from dependency_injector import providers +from typing import Any +from dependency_injector import providers # Test 1: to check the getattr type provider1 = providers.DependenciesContainer( a=providers.Provider(), b=providers.Provider(), ) -a1: providers.Provider = provider1.a -b1: providers.Provider = provider1.b +a1: providers.Provider[Any] = provider1.a +b1: providers.Provider[Any] = provider1.b c1: providers.ProvidedInstance = provider1.c.provided diff --git a/tests/typing/dependency.py b/tests/typing/dependency.py index a699e4c2..10711f93 100644 --- a/tests/typing/dependency.py +++ b/tests/typing/dependency.py @@ -1,15 +1,14 @@ -from typing import Type +from typing import Any, Type from dependency_injector import providers -class Animal: - ... +class Animal: ... class Cat(Animal): - def __init__(self, *_, **__): ... + def __init__(self, *a: Any, **kw: Any) -> None: ... # Test 1: to check the return type @@ -23,6 +22,8 @@ var2: Type[Animal] = provider2.instance_of # 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_() diff --git a/tests/typing/dict.py b/tests/typing/dict.py index f676b67d..2a6b0044 100644 --- a/tests/typing/dict.py +++ b/tests/typing/dict.py @@ -2,7 +2,6 @@ from typing import Any, Dict from dependency_injector import providers - # Test 1: to check the return type (class) provider1 = providers.Dict( a1=providers.Factory(object), @@ -17,7 +16,9 @@ var2: Dict[Any, Any] = provider2() # Test 3: to check init with non-string keys -provider3 = providers.Dict({object(): providers.Factory(object)}, a2=providers.Factory(object)) +provider3 = providers.Dict( + {object(): providers.Factory(object)}, a2=providers.Factory(object) +) var3: Dict[Any, Any] = provider3() @@ -42,6 +43,8 @@ provider6 = providers.Dict( a1=providers.Factory(object), a2=providers.Factory(object), ) + + async def _async3() -> None: var1: Dict[Any, Any] = await provider6() # type: ignore var2: Dict[Any, Any] = await provider6.async_() diff --git a/tests/typing/dynamic_container.py b/tests/typing/dynamic_container.py index 69bc764d..b88da6bd 100644 --- a/tests/typing/dynamic_container.py +++ b/tests/typing/dynamic_container.py @@ -1,8 +1,7 @@ -from typing import Dict +from typing import Any, Dict from dependency_injector import containers, providers - # Test 1: to check setattr container1 = containers.DynamicContainer() container1.abc = providers.Provider() @@ -23,7 +22,7 @@ container4.set_providers(a=providers.Provider()) # Test 5: to check .dependencies attribute container5 = containers.DynamicContainer() -dependencies: Dict[str, providers.Provider] = container5.dependencies +dependencies: Dict[str, providers.Provider[Any]] = container5.dependencies # Test 6: to check base class container6: containers.Container = containers.DynamicContainer() diff --git a/tests/typing/factory.py b/tests/typing/factory.py index 089bef07..29b34823 100644 --- a/tests/typing/factory.py +++ b/tests/typing/factory.py @@ -1,15 +1,14 @@ -from typing import Callable, Optional, Tuple, Any, Dict, Type +from typing import Any, Callable, Dict, Optional, Tuple, Type from dependency_injector import providers -class Animal: - ... +class Animal: ... class Cat(Animal): - def __init__(self, *_, **__): ... + def __init__(self, *a: Any, **kw: Any) -> None: ... @classmethod def create(cls) -> Animal: @@ -63,17 +62,29 @@ factory_a_9: providers.Factory[str] = provider9.a factory_b_9: providers.Factory[str] = provider9.b val9: str = provider9("a") -provider9_set_non_string_keys: providers.FactoryAggregate[str] = providers.FactoryAggregate() -provider9_set_non_string_keys.set_factories({Cat: providers.Factory(str, "str")}) -factory_set_non_string_9: providers.Factory[str] = provider9_set_non_string_keys.factories[Cat] - -provider9_new_non_string_keys: providers.FactoryAggregate[str] = providers.FactoryAggregate( - {Cat: providers.Factory(str, "str")}, +provider9_set_non_string_keys: providers.FactoryAggregate[str] = ( + providers.FactoryAggregate() +) +provider9_set_non_string_keys.set_factories({Cat: providers.Factory(str, "str")}) +factory_set_non_string_9: providers.Factory[str] = ( + provider9_set_non_string_keys.factories[Cat] ) -factory_new_non_string_9: providers.Factory[str] = provider9_new_non_string_keys.factories[Cat] -provider9_no_explicit_typing = providers.FactoryAggregate(a=providers.Factory(str, "str")) -provider9_no_explicit_typing_factory: providers.Factory[str] = provider9_no_explicit_typing.factories["a"] +provider9_new_non_string_keys: providers.FactoryAggregate[str] = ( + providers.FactoryAggregate( + {Cat: providers.Factory(str, "str")}, + ) +) +factory_new_non_string_9: providers.Factory[str] = ( + provider9_new_non_string_keys.factories[Cat] +) + +provider9_no_explicit_typing = providers.FactoryAggregate( + a=providers.Factory(str, "str") +) +provider9_no_explicit_typing_factory: providers.Factory[str] = ( + provider9_no_explicit_typing.factories["a"] +) provider9_no_explicit_typing_object: str = provider9_no_explicit_typing("a") # Test 10: to check the explicit typing @@ -82,10 +93,13 @@ animal10: Animal = factory10() # Test 11: to check the return type with await provider11 = providers.Factory(Cat) + + async def _async11() -> None: animal1: Animal = await provider11(1, 2, 3, b="1", c=2, e=0.0) # type: ignore animal2: Animal = await provider11.async_(1, 2, 3, b="1", c=2, e=0.0) + # Test 12: to check class type from .provides provider12 = providers.Factory(Cat) provided_cls12: Type[Animal] = provider12.cls @@ -101,5 +115,5 @@ provided_provides13: Optional[Callable[..., Animal]] = provider13.provides assert provided_provides13 is not None and provided_provides13() == Cat() # Test 14: to check string imports -provider14: providers.Factory[dict] = providers.Factory("builtins.dict") +provider14: providers.Factory[Dict[Any, Any]] = providers.Factory("builtins.dict") provider14.set_provides("builtins.dict") diff --git a/tests/typing/list.py b/tests/typing/list.py index d29baadb..65e65e78 100644 --- a/tests/typing/list.py +++ b/tests/typing/list.py @@ -1,8 +1,7 @@ -from typing import Tuple, Any, List +from typing import Any, List, Tuple from dependency_injector import providers - # Test 1: to check the return type (class) provider1 = providers.List( providers.Factory(object), @@ -33,6 +32,8 @@ provider4 = providers.List( providers.Factory(object), providers.Factory(object), ) + + async def _async4() -> None: var1: List[Any] = await provider4() # type: ignore var2: List[Any] = await provider4.async_() diff --git a/tests/typing/object.py b/tests/typing/object.py index 103071ae..739b6238 100644 --- a/tests/typing/object.py +++ b/tests/typing/object.py @@ -1,8 +1,7 @@ -from typing import Type, Optional +from typing import Optional, Type from dependency_injector import providers - # Test 1: to check the return type provider1 = providers.Object(int(3)) var1: int = provider1() @@ -16,10 +15,13 @@ method_caller2: providers.MethodCaller = provider2.provided.method.call(123, arg # Test 3: to check the return type with await provider3 = providers.Object(int(3)) + + async def _async3() -> None: var1: int = await provider3() # type: ignore var2: int = await provider3.async_() + # Test 4: to check class type from provider provider4 = providers.Object(int("1")) provided_provides: Optional[int] = provider4.provides diff --git a/tests/typing/provider.py b/tests/typing/provider.py index 18afd69a..cb832b77 100644 --- a/tests/typing/provider.py +++ b/tests/typing/provider.py @@ -1,5 +1,6 @@ -from dependency_injector import providers +from typing import Any +from dependency_injector import providers # Test 1: to check .provided attribute provider1: providers.Provider[int] = providers.Object(1) @@ -7,7 +8,7 @@ provided: int = provider1.provided() provider1_delegate: providers.Provider[int] = provider1.provider # Test 2: to check async mode API -provider2: providers.Provider = providers.Provider() +provider2: providers.Provider[Any] = providers.Provider() provider2.enable_async_mode() provider2.disable_async_mode() provider2.reset_async_mode() diff --git a/tests/typing/resource.py b/tests/typing/resource.py index 113ced5a..d01a5106 100644 --- a/tests/typing/resource.py +++ b/tests/typing/resource.py @@ -1,4 +1,13 @@ -from typing import List, Iterator, Generator, AsyncIterator, AsyncGenerator, Optional +from typing import ( + Any, + AsyncGenerator, + AsyncIterator, + Dict, + Generator, + Iterator, + List, + Optional, +) from dependency_injector import providers, resources @@ -32,11 +41,10 @@ var3: List[int] = provider3() # Test 4: to check the return type with resource subclass class MyResource4(resources.Resource[List[int]]): - def init(self, *args, **kwargs) -> List[int]: + def init(self, *args: Any, **kwargs: Any) -> List[int]: return [] - def shutdown(self, resource: Optional[List[int]]) -> None: - ... + def shutdown(self, resource: Optional[List[int]]) -> None: ... provider4 = providers.Resource(MyResource4) @@ -84,11 +92,10 @@ async def _provide7() -> None: # Test 8: to check the return type with async resource subclass class MyResource8(resources.AsyncResource[List[int]]): - async def init(self, *args, **kwargs) -> List[int]: + async def init(self, *args: Any, **kwargs: Any) -> List[int]: return [] - async def shutdown(self, resource: Optional[List[int]]) -> None: - ... + async def shutdown(self, resource: Optional[List[int]]) -> None: ... provider8 = providers.Resource(MyResource8) @@ -100,5 +107,5 @@ async def _provide8() -> None: # Test 9: to check string imports -provider9: providers.Resource[dict] = providers.Resource("builtins.dict") +provider9: providers.Resource[Dict[Any, Any]] = providers.Resource("builtins.dict") provider9.set_provides("builtins.dict") diff --git a/tests/typing/selector.py b/tests/typing/selector.py index e6d092c5..5d89ec66 100644 --- a/tests/typing/selector.py +++ b/tests/typing/selector.py @@ -2,7 +2,6 @@ from typing import Any from dependency_injector import providers - # Test 1: to check the return type provider1 = providers.Selector( lambda: "a", @@ -28,7 +27,7 @@ provider3 = providers.Selector( a=providers.Factory(object), b=providers.Factory(object), ) -attr3: providers.Provider = provider3.a +attr3: providers.Provider[Any] = provider3.a # Test 4: to check the return type with await provider4 = providers.Selector( @@ -36,6 +35,8 @@ provider4 = providers.Selector( a=providers.Factory(object), b=providers.Factory(object), ) + + async def _async4() -> None: - var1: Any = await provider4() # type: ignore + var1: Any = await provider4() var2: Any = await provider4.async_() diff --git a/tests/typing/singleton.py b/tests/typing/singleton.py index 8dc3df23..740da8b9 100644 --- a/tests/typing/singleton.py +++ b/tests/typing/singleton.py @@ -1,15 +1,14 @@ -from typing import Callable, Optional, Tuple, Any, Dict, Type +from typing import Any, Callable, Dict, Optional, Tuple, Type from dependency_injector import providers -class Animal: - ... +class Animal: ... class Cat(Animal): - def __init__(self, *_, **__): ... + def __init__(self, *a: Any, **kw: Any) -> None: ... @classmethod def create(cls) -> Animal: @@ -72,10 +71,13 @@ provider12 = providers.SingletonDelegate(providers.Singleton(object)) # Test 13: to check the return type with await provider13 = providers.Singleton(Cat) + + async def _async13() -> None: animal1: Animal = await provider13(1, 2, 3, b="1", c=2, e=0.0) # type: ignore animal2: Animal = await provider13.async_(1, 2, 3, b="1", c=2, e=0.0) + # Test 14: to check class from .provides provider14 = providers.Singleton(Cat) provided_cls14: Type[Cat] = provider14.cls @@ -91,5 +93,5 @@ provided_provides15: Optional[Callable[..., Animal]] = provider15.provides assert provided_provides15 is not None and provided_provides15() == Cat() # Test 16: to check string imports -provider16: providers.Singleton[dict] = providers.Singleton("builtins.dict") +provider16: providers.Singleton[Dict[Any, Any]] = providers.Singleton("builtins.dict") provider16.set_provides("builtins.dict") diff --git a/tox.ini b/tox.ini index 705ea890..b2c5e79f 100644 --- a/tox.ini +++ b/tox.ini @@ -88,4 +88,4 @@ deps= pydantic-settings mypy commands= - mypy tests/typing + mypy --strict tests/typing From 1ae96e3eeb801caffd8cf53c8e985ba5f531e871 Mon Sep 17 00:00:00 2001 From: ZipFile Date: Fri, 30 May 2025 19:44:47 +0000 Subject: [PATCH 5/6] Use `windows-2022` GHA image for building wheels --- .github/workflows/publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publishing.yml b/.github/workflows/publishing.yml index af4e1cd1..0151704c 100644 --- a/.github/workflows/publishing.yml +++ b/.github/workflows/publishing.yml @@ -60,7 +60,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-24.04, ubuntu-24.04-arm, windows-2019, macos-14] + os: [ubuntu-24.04, ubuntu-24.04-arm, windows-2022, macos-14] env: CIBW_ENABLE: pypy CIBW_ENVIRONMENT: >- From 16f444b230f4de0ea15c3ce729d2b93d2a471cd1 Mon Sep 17 00:00:00 2001 From: ZipFile Date: Fri, 30 May 2025 19:50:21 +0000 Subject: [PATCH 6/6] Bump version --- src/dependency_injector/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dependency_injector/__init__.py b/src/dependency_injector/__init__.py index c97f7e90..90e6570b 100644 --- a/src/dependency_injector/__init__.py +++ b/src/dependency_injector/__init__.py @@ -1,6 +1,6 @@ """Top-level package.""" -__version__ = "4.47.0" +__version__ = "4.47.1" """Version number. :type: str