Repository: reagento/dishka
Pull request #134 (2024-04-19 09:18:16)

allow to use FromComponent as a factory result


Patch:
diff --git a/src/dishka/dependency_source/make_factory.py b/src/dishka/dependency_source/make_factory.py
index 6564de4..d9f91b9 100644
--- a/src/dishka/dependency_source/make_factory.py
+++ b/src/dishka/dependency_source/make_factory.py
@@ -19,6 +19,7 @@ from inspect import (
     unwrap,
 )
 from typing import (
+    Annotated,
     Any,
     Protocol,
     get_args,
@@ -37,7 +38,10 @@ from dishka._adaptix.type_tools.generic_resolver import (
     GenericResolver,
     MembersStorage,
 )
-from dishka.entities.key import DependencyKey, hints_to_dependency_keys
+from dishka.entities.key import (
+    hint_to_dependency_key,
+    hints_to_dependency_keys,
+)
 from dishka.entities.scope import BaseScope
 from .composite import CompositeDependencySource, ensure_composite
 from .factory import Factory, FactoryType
@@ -177,6 +181,11 @@ def _make_factory_by_class(
         source: Callable,
         cache: bool,
 ) -> Factory:
+    if not provides:
+        provides = source
+
+    if get_origin(source) is Annotated:
+        source = get_args(source)[0]
     init = strip_alias(source).__init__
     if missing_hints := _params_without_hints(init, skip_self=True):
         name = f"{source.__module__}.{source.__qualname__}.__init__"
@@ -200,17 +209,16 @@ def _make_factory_by_class(
             f"Or, create a separate factory with all types imported.",
             name=e.name,
         ) from e
+
     hints.pop("return", _empty)
     dependencies = list(hints.values())
-    if not provides:
-        provides = source
 
     return Factory(
         dependencies=hints_to_dependency_keys(dependencies),
         type_=FactoryType.FACTORY,
         source=source,
         scope=scope,
-        provides=DependencyKey(provides, None),
+        provides=hint_to_dependency_key(provides),
         is_to_bind=False,
         cache=cache,
     )
@@ -272,7 +280,7 @@ def _make_factory_by_method(
         type_=factory_type,
         source=source,
         scope=scope,
-        provides=DependencyKey(provides, None),
+        provides=hint_to_dependency_key(provides),
         is_to_bind=is_in_class,
         cache=cache,
     )
@@ -322,7 +330,7 @@ def _make_factory_by_static_method(
         type_=factory_type,
         source=source,
         scope=scope,
-        provides=DependencyKey(provides, None),
+        provides=hint_to_dependency_key(provides),
         is_to_bind=False,
         cache=cache,
     )


Test patch:
diff --git a/tests/unit/container/test_components.py b/tests/unit/container/test_components.py
index 492c7a0..25022d3 100644
--- a/tests/unit/container/test_components.py
+++ b/tests/unit/container/test_components.py
@@ -214,3 +214,24 @@ def test_decorator():
     container = make_container(provider, x_provider, dec_provider)
     assert container.get(int, component="X") == 2
     assert container.get(int) == 100
+
+
+class ResultProvider(Provider):
+    scope = Scope.APP
+    component = "X"
+
+    @provide
+    def foo(self) -> int:
+        return 42
+
+    @provide
+    def bar(self, x: int) -> Annotated[float, FromComponent()]:
+        return x
+
+
+def test_result_component():
+    container = make_container(ResultProvider())
+    assert container.get(float) == 42
+
+    container = make_container(ResultProvider().to_component("YYY"))
+    assert container.get(float) == 42