Skip to content

Commit 8460465

Browse files
committed
Merge branch 'release/4.47.1'
2 parents 193249f + 16f444b commit 8460465

25 files changed

+247
-114
lines changed

.github/workflows/publishing.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ jobs:
6060
runs-on: ${{ matrix.os }}
6161
strategy:
6262
matrix:
63-
os: [ubuntu-24.04, ubuntu-24.04-arm, windows-2019, macos-14]
63+
os: [ubuntu-24.04, ubuntu-24.04-arm, windows-2022, macos-14]
6464
env:
6565
CIBW_ENABLE: pypy
6666
CIBW_ENVIRONMENT: >-
6767
PIP_CONFIG_SETTINGS="build_ext=-j4"
6868
DEPENDENCY_INJECTOR_LIMITED_API="1"
69+
CFLAGS="-g0"
6970
steps:
7071
- uses: actions/checkout@v3
7172
- name: Build wheels

src/dependency_injector/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Top-level package."""
22

3-
__version__ = "4.47.0"
3+
__version__ = "4.47.1"
44
"""Version number.
55
66
:type: str

src/dependency_injector/_cwiring.pyi

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import Any, Awaitable, Callable, Dict, Tuple, TypeVar
2+
3+
from .providers import Provider
4+
5+
T = TypeVar("T")
6+
7+
def _sync_inject(
8+
fn: Callable[..., T],
9+
args: Tuple[Any, ...],
10+
kwargs: Dict[str, Any],
11+
injections: Dict[str, Provider[Any]],
12+
closings: Dict[str, Provider[Any]],
13+
/,
14+
) -> T: ...
15+
async def _async_inject(
16+
fn: Callable[..., Awaitable[T]],
17+
args: Tuple[Any, ...],
18+
kwargs: Dict[str, Any],
19+
injections: Dict[str, Provider[Any]],
20+
closings: Dict[str, Provider[Any]],
21+
/,
22+
) -> T: ...
23+
def _isawaitable(instance: Any) -> bool: ...

src/dependency_injector/containers.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class WiringConfiguration:
4141
class Container:
4242
provider_type: Type[Provider] = Provider
4343
providers: Dict[str, Provider]
44-
dependencies: Dict[str, Provider]
44+
dependencies: Dict[str, Provider[Any]]
4545
overridden: Tuple[Provider]
4646
wiring_config: WiringConfiguration
4747
auto_load_config: bool = True

src/dependency_injector/wiring.py

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
import sys
99
from types import ModuleType
1010
from typing import (
11+
TYPE_CHECKING,
1112
Any,
1213
Callable,
1314
Dict,
14-
Generic,
1515
Iterable,
1616
Iterator,
1717
Optional,
18+
Protocol,
1819
Set,
1920
Tuple,
2021
Type,
@@ -23,6 +24,7 @@
2324
cast,
2425
)
2526

27+
from typing_extensions import Self
2628

2729
# Hotfix, see: https://github.com/ets-labs/python-dependency-injector/issues/362
2830
if sys.version_info >= (3, 9):
@@ -66,7 +68,6 @@ def get_origin(tp):
6668

6769
from . import providers
6870

69-
7071
__all__ = (
7172
"wire",
7273
"unwire",
@@ -89,7 +90,11 @@ def get_origin(tp):
8990

9091
T = TypeVar("T")
9192
F = TypeVar("F", bound=Callable[..., Any])
92-
Container = Any
93+
94+
if TYPE_CHECKING:
95+
from .containers import Container
96+
else:
97+
Container = Any
9398

9499

95100
class PatchedRegistry:
@@ -777,15 +782,15 @@ class RequiredModifier(Modifier):
777782
def __init__(self) -> None:
778783
self.type_modifier = None
779784

780-
def as_int(self) -> "RequiredModifier":
785+
def as_int(self) -> Self:
781786
self.type_modifier = TypeModifier(int)
782787
return self
783788

784-
def as_float(self) -> "RequiredModifier":
789+
def as_float(self) -> Self:
785790
self.type_modifier = TypeModifier(float)
786791
return self
787792

788-
def as_(self, type_: Type) -> "RequiredModifier":
793+
def as_(self, type_: Type) -> Self:
789794
self.type_modifier = TypeModifier(type_)
790795
return self
791796

@@ -833,15 +838,15 @@ class ProvidedInstance(Modifier):
833838
def __init__(self) -> None:
834839
self.segments = []
835840

836-
def __getattr__(self, item):
841+
def __getattr__(self, item: str) -> Self:
837842
self.segments.append((self.TYPE_ATTRIBUTE, item))
838843
return self
839844

840-
def __getitem__(self, item):
845+
def __getitem__(self, item) -> Self:
841846
self.segments.append((self.TYPE_ITEM, item))
842847
return self
843848

844-
def call(self):
849+
def call(self) -> Self:
845850
self.segments.append((self.TYPE_CALL, None))
846851
return self
847852

@@ -866,36 +871,56 @@ def provided() -> ProvidedInstance:
866871
return ProvidedInstance()
867872

868873

869-
class _Marker(Generic[T]):
874+
MarkerItem = Union[
875+
str,
876+
providers.Provider[Any],
877+
Tuple[str, TypeModifier],
878+
Type[Container],
879+
"_Marker",
880+
]
870881

871-
__IS_MARKER__ = True
872882

873-
def __init__(
874-
self,
875-
provider: Union[providers.Provider, Container, str],
876-
modifier: Optional[Modifier] = None,
877-
) -> None:
878-
if _is_declarative_container(provider):
879-
provider = provider.__self__
880-
self.provider = provider
881-
self.modifier = modifier
883+
if TYPE_CHECKING:
882884

883-
def __class_getitem__(cls, item) -> T:
884-
if isinstance(item, tuple):
885-
return cls(*item)
886-
return cls(item)
885+
class _Marker(Protocol):
886+
__IS_MARKER__: bool
887887

888-
def __call__(self) -> T:
889-
return self
888+
def __call__(self) -> Self: ...
889+
def __getattr__(self, item: str) -> Self: ...
890+
def __getitem__(self, item: Any) -> Any: ...
891+
892+
Provide: _Marker
893+
Provider: _Marker
894+
Closing: _Marker
895+
else:
890896

897+
class _Marker:
891898

892-
class Provide(_Marker): ...
899+
__IS_MARKER__ = True
893900

901+
def __init__(
902+
self,
903+
provider: Union[providers.Provider, Container, str],
904+
modifier: Optional[Modifier] = None,
905+
) -> None:
906+
if _is_declarative_container(provider):
907+
provider = provider.__self__
908+
self.provider = provider
909+
self.modifier = modifier
894910

895-
class Provider(_Marker): ...
911+
def __class_getitem__(cls, item: MarkerItem) -> Self:
912+
if isinstance(item, tuple):
913+
return cls(*item)
914+
return cls(item)
896915

916+
def __call__(self) -> Self:
917+
return self
897918

898-
class Closing(_Marker): ...
919+
class Provide(_Marker): ...
920+
921+
class Provider(_Marker): ...
922+
923+
class Closing(_Marker): ...
899924

900925

901926
class AutoLoader:
@@ -998,8 +1023,8 @@ def is_loader_installed() -> bool:
9981023
_loader = AutoLoader()
9991024

10001025
# Optimizations
1001-
from ._cwiring import _sync_inject # noqa
10021026
from ._cwiring import _async_inject # noqa
1027+
from ._cwiring import _sync_inject # noqa
10031028

10041029

10051030
# Wiring uses the following Python wrapper because there is
@@ -1028,13 +1053,17 @@ def _patched(*args, **kwargs):
10281053
patched.injections,
10291054
patched.closing,
10301055
)
1056+
10311057
return cast(F, _patched)
10321058

10331059

10341060
if sys.version_info >= (3, 10):
1061+
10351062
def _get_annotations(obj: Any) -> Dict[str, Any]:
10361063
return inspect.get_annotations(obj)
1064+
10371065
else:
1066+
10381067
def _get_annotations(obj: Any) -> Dict[str, Any]:
10391068
return getattr(obj, "__annotations__", {})
10401069

tests/typing/aggregate.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
from dependency_injector import providers
22

33

4-
class Animal:
5-
...
4+
class Animal: ...
65

76

8-
class Cat(Animal):
9-
...
7+
class Cat(Animal): ...
108

119

1210
# Test 1: to check Aggregate provider
@@ -20,13 +18,19 @@ class Cat(Animal):
2018

2119
provider1_set_non_string_keys: providers.Aggregate[str] = providers.Aggregate()
2220
provider1_set_non_string_keys.set_providers({Cat: providers.Object("str")})
23-
provider_set_non_string_1: providers.Provider[str] = provider1_set_non_string_keys.providers[Cat]
21+
provider_set_non_string_1: providers.Provider[str] = (
22+
provider1_set_non_string_keys.providers[Cat]
23+
)
2424

2525
provider1_new_non_string_keys: providers.Aggregate[str] = providers.Aggregate(
2626
{Cat: providers.Object("str")},
2727
)
28-
factory_new_non_string_1: providers.Provider[str] = provider1_new_non_string_keys.providers[Cat]
28+
factory_new_non_string_1: providers.Provider[str] = (
29+
provider1_new_non_string_keys.providers[Cat]
30+
)
2931

3032
provider1_no_explicit_typing = providers.Aggregate(a=providers.Object("str"))
31-
provider1_no_explicit_typing_factory: providers.Provider[str] = provider1_no_explicit_typing.providers["a"]
33+
provider1_no_explicit_typing_factory: providers.Provider[str] = (
34+
provider1_no_explicit_typing.providers["a"]
35+
)
3236
provider1_no_explicit_typing_object: str = provider1_no_explicit_typing("a")

tests/typing/callable.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
from typing import Callable, Optional, Tuple, Any, Dict, Type
1+
from typing import Any, Callable, Dict, Optional, Tuple, Type
22

33
from dependency_injector import providers
44

55

6-
class Animal:
7-
...
6+
class Animal: ...
87

98

109
class Cat(Animal):
@@ -53,10 +52,13 @@ def create(cls) -> Animal:
5352

5453
# Test 9: to check the return type with await
5554
provider9 = providers.Callable(Cat)
55+
56+
5657
async def _async9() -> None:
5758
animal1: Animal = await provider9(1, 2, 3, b="1", c=2, e=0.0) # type: ignore
5859
animal2: Animal = await provider9.async_(1, 2, 3, b="1", c=2, e=0.0)
5960

61+
6062
# Test 10: to check the .provides
6163
provider10 = providers.Callable(Cat)
6264
provides10: Optional[Callable[..., Cat]] = provider10.provides
@@ -68,5 +70,5 @@ async def _async9() -> None:
6870
assert provides11 is Cat
6971

7072
# Test 12: to check string imports
71-
provider12: providers.Callable[dict] = providers.Callable("builtins.dict")
73+
provider12: providers.Callable[Dict[Any, Any]] = providers.Callable("builtins.dict")
7274
provider12.set_provides("builtins.dict")

tests/typing/configuration.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from pathlib import Path
2-
from typing import Any
2+
from typing import Any, Dict
33

4-
from dependency_injector import providers
54
from pydantic_settings import BaseSettings as PydanticSettings
65

6+
from dependency_injector import providers
77

88
# Test 1: to check the getattr
99
config1: providers.Configuration = providers.Configuration()
10-
provider1: providers.Provider[dict] = providers.Factory(dict, a=config1.a)
10+
provider1: providers.Provider[Dict[str, Any]] = providers.Factory(dict, a=config1.a)
1111

1212
# Test 2: to check the from_*() method
1313
config2 = providers.Configuration()
@@ -68,7 +68,9 @@
6868
pydantic_settings=[PydanticSettings()],
6969
)
7070
config5_pydantic.set_pydantic_settings([PydanticSettings()])
71-
config5_pydantic_settings: list[PydanticSettings] = config5_pydantic.get_pydantic_settings()
71+
config5_pydantic_settings: list[PydanticSettings] = (
72+
config5_pydantic.get_pydantic_settings()
73+
)
7274

7375
# Test 6: to check init arguments
7476
config6 = providers.Configuration(

tests/typing/container.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
from typing import Any
2+
13
from dependency_injector import providers
24

35

4-
class Container:
5-
...
6+
class Container: ...
67

78

89
# Test 1: to check the return type
@@ -11,4 +12,4 @@ class Container:
1112

1213
# Test 2: to check the getattr
1314
provider2 = providers.Container(Container)
14-
attr: providers.Provider = provider2.attr
15+
attr: providers.Provider[Any] = provider2.attr

tests/typing/coroutine.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
from typing import Coroutine
1+
from typing import Awaitable, Coroutine
22

33
from dependency_injector import providers
44

55

6-
async def _coro() -> None:
7-
...
6+
async def _coro() -> None: ...
7+
88

99
# Test 1: to check the return type
1010
provider1 = providers.Coroutine(_coro)
11-
var1: Coroutine = provider1()
11+
var1: Awaitable[None] = provider1()
1212

1313
# Test 2: to check string imports
1414
provider2: providers.Coroutine[None] = providers.Coroutine("_coro")

0 commit comments

Comments
 (0)