ets-labs/python-dependency-injector

Dependency Injector 4.48.0+ returns _asyncio.Task instance instead of class instance

Opened this issue · 1 comments

For Dependency Injector versions 4.48.0 and above, the app variable is initialized as an instance of _asyncio.Task:

from faststream import FastStream
from faststream.rabbit import RabbitBroker
from dependency_injector import containers, providers

class DI(containers.DeclarativeContainer):
    broker = providers.Resource(
        RabbitBroker,
    )

    app = providers.Resource(
        FastStream,
        broker=broker,
    )

di = DI()
di.init_resources()
app = di.app()

print(type(app))

However, if we change the broker provider type from Resource to Factory, the app variable correctly returns an instance of faststream.app.FastStream (as expected):

from faststream import FastStream
from faststream.rabbit import RabbitBroker
from dependency_injector import containers, providers

class DI(containers.DeclarativeContainer):
    broker = providers.Factory(
        RabbitBroker,
    )

    app = providers.Resource(
        FastStream,
        broker=broker,
    )

di = DI()
di.init_resources()
app = di.app()

print(type(app))

In Dependency Injector versions 4.47.1 and below, the app variable consistently returns an instance of faststream.app.FastStream, regardless of whether the broker is initialized as Resource or Factory.

Question: Why does Dependency Injector 4.48.0+ return an _asyncio.Task instance instead of faststream.app.FastStream when using providers.Resource?

Current Workaround: We've temporarily resolved the issue by downgrading to Dependency Injector version 4.47.1.

This is expected behavior since v4.48.0, see docs. RabbitBroker implements async context manager protocol, so we try to initialize it (call to __aenter__) in the Resource provider. app became async because it has async dependency now (broker).

If you want behavior close to one that was in previous version, consider using Singleton provider.