Skip to content

Resource is not detected by container.init_resources() when declaration is not at class root level #380

Open
@approxit

Description

@approxit

Howdy, another somewhat similar issue like #379, this time with providers.Resource.

Consider this example:

from dependency_injector import providers, containers
import asyncio


class TestObject():
	def __init__(self, foo, bar):
		self.foo = foo
		self.bar = bar


def sync_foo(foo):
	print('sync foo triggered!')
	return foo


async def async_foo(foo):
	print('async foo triggered!')
	await asyncio.sleep(0)
	return foo


class RootResourceContainer(containers.DeclarativeContainer):
	sync_foo_resource=providers.Resource(
		sync_foo,
		foo='bar'
	)
	async_foo_resource=providers.Resource(
		async_foo,
		foo='bar'
	)

	obj_factory = providers.DelegatedFactory(
		TestObject,
		foo=async_foo_resource,
		bar=sync_foo_resource,
	)


class NonRootResourceContainer(containers.DeclarativeContainer):
	obj_factory = providers.DelegatedFactory(
		TestObject,
		foo=providers.Resource(
			async_foo,
			foo='bar'
		),
		bar=providers.Resource(
			sync_foo,
			foo='bar'
		)
	)


async def main():
	container = RootResourceContainer()
	await container.init_resources()
	print('after init')
	print(container.obj_factory())
	await container.shutdown_resources()

	print('----')

	container = NonRootResourceContainer()
	await container.init_resources()  # Crashing as async non-root async Resource is not detected
	print('after init')
	print(container.obj_factory())
	await container.shutdown_resources()


asyncio.run(main())

First container with everything defined at class root level works, as both Resources are detected and initialized by container.init_resources().
Second container with nested Resources definition can't figure it out, and container.init_resources() is not picking up all resources as stated in docs. In result, if no async resources are found, container.init_resources() will not be awaitable, and awaiting it will crash.

Also in first container by calling container.obj_factory() we are receiving awaitable, not actual factory result. As I'm expecting to receive awaitable when there was no previous async Resource initialization and handle this somewhere in my code (as stated in docs), that I'm expecting container.init_resources() to do the job and resolve every declared resource and get rid of awaiting anything inside my code. Or in another words - I'd like to keep Resource-specific logic at the container layer, without bleeding it into my code, which will be sensitive for IoC layer changes.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions