Skip to content

Commit ed5d972

Browse files
committed
Fix issues where tagged constructor injection didn't work in python 3.7.
1 parent e6ff2e7 commit ed5d972

File tree

4 files changed

+49
-28
lines changed

4 files changed

+49
-28
lines changed

src/dependency_injection/container.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,45 +222,46 @@ def _inject_dependencies(
222222
dependencies = {}
223223
for param_name, param_info in params.items():
224224
if param_name != "self":
225-
# Check for *args and **kwargs
226225
if param_info.kind == inspect.Parameter.VAR_POSITIONAL:
227-
# *args parameter
228226
pass
229227
elif param_info.kind == inspect.Parameter.VAR_KEYWORD:
230-
# **kwargs parameter
231228
pass
232229
else:
233-
# Priority 1: Check if constructor_args has argument with same name
234230
if constructor_args and param_name in constructor_args:
235231
dependencies[param_name] = constructor_args[param_name]
236232
else:
237-
# Priority 2: Handle List[Tagged], List[AnyTagged[...]], ...
238-
tagged_dependencies = []
239233
if (
240234
hasattr(param_info.annotation, "__origin__")
241235
and param_info.annotation.__origin__ is list
242236
):
243237
inner_type = param_info.annotation.__args__[0]
244238

245-
if isinstance(inner_type, Tagged):
239+
tagged_dependencies = []
240+
if isinstance(inner_type, type) and issubclass(
241+
inner_type, Tagged
242+
):
243+
tagged_type = inner_type.tag
246244
tagged_dependencies = self.resolve_all(
247-
tags={inner_type.tag}
245+
tags={tagged_type}
248246
)
249247

250-
elif isinstance(inner_type, AnyTagged):
248+
elif isinstance(inner_type, type) and issubclass(
249+
inner_type, AnyTagged
250+
):
251251
tagged_dependencies = self.resolve_all(
252252
tags=inner_type.tags, match_all_tags=False
253253
)
254254

255-
elif isinstance(inner_type, AllTagged):
255+
elif isinstance(inner_type, type) and issubclass(
256+
inner_type, AllTagged
257+
):
256258
tagged_dependencies = self.resolve_all(
257259
tags=inner_type.tags, match_all_tags=True
258260
)
259261

260262
dependencies[param_name] = tagged_dependencies
261263

262264
else:
263-
# Priority 3: Regular type resolution
264265
try:
265266
dependencies[param_name] = self.resolve(
266267
param_info.annotation, scope_name=scope_name
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
from typing import Type, Tuple, Set, Union
1+
from typing import Generic, Set, Tuple, Type, TypeVar, Union
22

3+
T = TypeVar("T")
34

4-
class AllTagged:
5-
def __init__(self, tags: Tuple[Type, ...]):
6-
self.tags: Set[Type] = set(tags)
5+
6+
class AllTagged(Generic[T]):
7+
def __init__(self, tags: Tuple[Type[T], ...]):
8+
self.tags: Set[Type[T]] = set(tags)
79

810
@classmethod
9-
def __class_getitem__(cls, item: Union[Type, Tuple[Type, ...]]) -> "AllTagged":
11+
def __class_getitem__(
12+
cls, item: Union[Type[T], Tuple[Type[T], ...]]
13+
) -> Type["AllTagged"]:
1014
if not isinstance(item, tuple):
1115
item = (item,)
12-
return cls(item)
16+
return type(
17+
f'AllTagged_{"_".join([t.__name__ for t in item])}',
18+
(cls,),
19+
{"tags": set(item)},
20+
)
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
from typing import Type, Tuple, Set, Union
1+
from typing import Type, Generic, TypeVar, Tuple, Union, Set
22

3+
T = TypeVar("T")
34

4-
class AnyTagged:
5-
def __init__(self, tags: Union[Tuple[Type, ...], Type]):
5+
6+
class AnyTagged(Generic[T]):
7+
def __init__(self, tags: Union[Tuple[Type[T], ...], Type[T]]):
68
if not isinstance(tags, tuple):
79
tags = (tags,)
8-
self.tags: Set[Type] = set(tags)
10+
self.tags: Set[Type[T]] = set(tags)
911

1012
@classmethod
11-
def __class_getitem__(cls, item: Union[Type, Tuple[Type, ...]]) -> "AnyTagged":
12-
return cls(item)
13+
def __class_getitem__(
14+
cls, item: Union[Type[T], Tuple[Type[T], ...]]
15+
) -> Type["AnyTagged"]:
16+
if not isinstance(item, tuple):
17+
item = (item,)
18+
return type(
19+
f'AnyTagged_{"_".join([t.__name__ for t in item])}',
20+
(cls,),
21+
{"tags": set(item)},
22+
)
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
from typing import Type
1+
from typing import Type, Generic, TypeVar
22

3+
T = TypeVar("T")
34

4-
class Tagged:
5-
def __init__(self, tag: Type):
5+
6+
class Tagged(Generic[T]):
7+
def __init__(self, tag: Type[T]):
68
self.tag = tag
79

810
@classmethod
9-
def __class_getitem__(cls, item: Type) -> "Tagged":
10-
return cls(item)
11+
def __class_getitem__(cls, item: Type[T]) -> Type["Tagged"]:
12+
return type(f"Tagged_{item.__name__}", (cls,), {"tag": item})

0 commit comments

Comments
 (0)