Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions modern_di_faststream/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
# Keys under which the containers live in FastStream's ``ContextRepo``. Each is
# written in one place and read in another; naming them keeps writer and reader
# in provable agreement instead of relying on two matching string literals.
_ROOT_CONTAINER_KEY = "di_container"
_REQUEST_CONTAINER_KEY = "request_container"
_ROOT_CONTAINER_KEY = "modern_di_root_container"
_REQUEST_CONTAINER_KEY = "modern_di_request_container"

_MISSING_REQUEST_CONTAINER = (
"No request container for this message, so the DI middleware did not run for it. "
Expand Down Expand Up @@ -99,7 +99,7 @@ class Dependency(typing.Generic[T_co]):
marker: integrations.Marker[T_co]

async def __call__(self, context: faststream.ContextRepo) -> T_co:
request_container: Container | None = context.get(_REQUEST_CONTAINER_KEY)
request_container: Container | None = context.get_local(_REQUEST_CONTAINER_KEY)
if request_container is None:
raise RuntimeError(_MISSING_REQUEST_CONTAINER)
return self.marker.resolve(request_container)
Expand Down
24 changes: 23 additions & 1 deletion tests/test_faststream_di.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ def test_fetch_di_container(app: faststream.FastStream) -> None:
assert isinstance(di_container, Container)


def test_fetch_di_container_ignores_a_user_global_named_di_container() -> None:
app_ = faststream.FastStream(NatsBroker())
container = modern_di_faststream.setup_di(app_, container=Container(groups=[Dependencies]))
app_.context.set_global("di_container", "user value")

assert modern_di_faststream.fetch_di_container(app_) is container


async def test_from_di_ignores_a_user_global_named_request_container() -> None:
broker = NatsBroker()
app_ = faststream.FastStream(broker)
modern_di_faststream.setup_di(app_, container=Container(groups=[Dependencies]))
broker.context.set_global("request_container", "user value")
resolved: list[SimpleCreator] = []
_subscribe_resolving(broker, TEST_SUBJECT, resolved)

async with TestNatsBroker(broker) as br, TestApp(app_):
await br.publish(None, TEST_SUBJECT)

assert [type(instance) for instance in resolved] == [SimpleCreator]


def _app_with_two_brokers(*, add_second_after_setup: bool) -> tuple[faststream.FastStream, NatsBroker, NatsBroker]:
first, second = NatsBroker(), NatsBroker()
app_ = faststream.FastStream(first) if add_second_after_setup else faststream.FastStream(first, second)
Expand Down Expand Up @@ -151,7 +173,7 @@ async def subscriber(instance: typing.Annotated[SimpleCreator, FromDI(Dependenci
async def test_from_di_without_setup_di_names_the_missing_step() -> None:
"""INVARIANT: ``FromDI`` on a message the DI middleware never saw fails by naming ``setup_di``.

Broken by handing ``ContextRepo.get``'s ``None`` straight to the marker, which surfaces as
Broken by handing ``ContextRepo.get_local``'s ``None`` straight to the marker, which surfaces as
modern-di's ``AttributeError: 'NoneType' object has no attribute 'resolve_dependency'`` and
points at nothing in this package.
"""
Expand Down
Loading