Repository: reagento/dishka (language: python)

Issue:
Clarify logic of context variables for multiple components
Add tests and ensure that everything is working as intended.


Discussion / hints:

Fix patch:
diff --git a/docs/advanced/context.rst b/docs/advanced/context.rst
index 7615e74f..2613480e 100644
--- a/docs/advanced/context.rst
+++ b/docs/advanced/context.rst
@@ -7,7 +7,7 @@ The difference from normal factories is that they are not created inside some ``
 
 Working with context data consists of three parts:
 
-1. Declaration that object is received from context using :ref:`from-context`. You need to provide the type and scope. Context data is available across all components.
+1. Declaration that object is received from context using :ref:`from-context`. You need to provide the type and scope.
 2. Usage of that object in providers. There is now difference how the object is
 3. Passing actual values on scope entrance. It can be container creation for top level scope or container calls for nested ones. Use it in form ``context={Type: value,...}``
 
@@ -35,3 +35,7 @@ Working with context data consists of three parts:
         # provide REQUEST-scoped context variable
         with container(context={Request:request}) as request_container:
              a = request_container.get(A)
+
+.. note::
+
+    If your are using *multiple components*, you need to specify ``from_context`` in them separately though the context is shared. Context data is always stored in default component, so, other components may not use it and have factories instead.
\ No newline at end of file


Test patch:
diff --git a/tests/unit/container/test_context_vars.py b/tests/unit/container/test_context_vars.py
index 1cac5877..664fb12a 100644
--- a/tests/unit/container/test_context_vars.py
+++ b/tests/unit/container/test_context_vars.py
@@ -57,3 +57,25 @@ def foo(self, a: int) -> float:
 
     container = make_async_container(MyProvider(), context={int: 1})
     assert await container.get(float, component="XXX") == 1
+
+
+@pytest.mark.asyncio
+async def test_2components_factory():
+    class DefaultProvider(Provider):
+        scope = Scope.APP
+        a = from_context(provides=int)
+
+    class MyProvider(Provider):
+        scope = Scope.APP
+        component = "XXX"
+
+        @provide
+        def get_int(self) -> int:
+            return 100
+
+        @provide
+        def foo(self, a: int) -> float:
+            return a
+
+    container = make_async_container(MyProvider(), context={int: 1})
+    assert await container.get(float, component="XXX") == 100