From da270e7a333c644f17e47aa22d476319c60c5476 Mon Sep 17 00:00:00 2001 From: nir Date: Tue, 24 Dec 2024 15:41:09 +0200 Subject: [PATCH] support resolve generic types that doesn't specify any type arguments. --- aioinject/context.py | 9 ++++++--- tests/features/test_generics.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/aioinject/context.py b/aioinject/context.py index b90ffcc..b30d5b1 100644 --- a/aioinject/context.py +++ b/aioinject/context.py @@ -115,9 +115,12 @@ async def resolve( for base in orig_bases: if is_generic_alias(base): args = base.__args__ - params = base.__origin__.__parameters__ - for param, arg in zip(params, args, strict=False): - args_map[param.__name__] = arg + if params := getattr(base.__origin__, "__parameters__", None): + for param, arg in zip(params, args, strict=False): + args_map[param.__name__] = arg + if not args_map: + # type may be generic though user didn't provide any type parameters + type_is_generic = False for dependency in provider.resolve_dependencies( diff --git a/tests/features/test_generics.py b/tests/features/test_generics.py index 02a64b1..8befe0b 100644 --- a/tests/features/test_generics.py +++ b/tests/features/test_generics.py @@ -168,3 +168,21 @@ def __init__(self, service: TwoGeneric[T, str]) -> None: assert isinstance(instance.service.b, WithGenericDependency) assert instance.service.a.dependency == MEANING_OF_LIFE_INT assert instance.service.b.dependency == MEANING_OF_LIFE_STR + + + +async def test_can_resolve_generic_class_without_parameters() -> None: + class GenericClass(Generic[T]): + def __init__(self, a: int) -> None: + self.a = a + + def so_generic(self) -> T: # pragma: no cover + raise NotImplementedError + + container = Container() + container.register(Scoped(GenericClass), Object(MEANING_OF_LIFE_INT)) + + async with container.context() as ctx: + instance = await ctx.resolve(GenericClass) + assert isinstance(instance, GenericClass) + assert instance.a == MEANING_OF_LIFE_INT