Skip to content

Resource provider to support context manager interface (__enter__/__exit__ and __aenter__/__aexit__) #444

Open
@ecs-jnguyen

Description

@ecs-jnguyen

I noticed that using provider.Resource() with container.init_resources() and container.shutdown_resources() does not call the __enter__ and/or __exit__ methods for a class or the @contextlib.contextmanager. For initializing and shutting down resources I had to make a wrapper method without @contextlib.contextmanager in order to call the __enter__ and __exit__ methods. Is this intended?

@contextlib.contextmanager
def this_does_not_work_by_it_self():
    print('entering this_does_not_work')
    yield None
    print('exiting this_does_not_work')

def this_works():
    print('entering this_works')
    with this_does_not_work_by_it_self() as x:
        yield x
    print('exiting this_works')

class SampleContainer(containers.DeclarativeContainer):

    # uncomment to see behavior
    # one = providers.Resource(this_does_not_work_by_it_self)

    """
    Output:
    main start init resources
    main done init resources
    main start shutdown resources
    main done shutdown resources
    """

    # uncomment to see behavior
    # two = providers.Resource(this_works)

    """
    Output:
    main start init resources
    entering this_works
    entering this_does_not_work
    main done init resources
    main start shutdown resources
    exiting this_does_not_work
    exiting this_works
    main done shutdown resources
    """


def main():
    container = SampleContainer()
    print('main start init resources')
    container.init_resources()
    print('main done init resources')
    print('main start shutdown resources')
    container.shutdown_resources()
    print('main done shutdown resources')

if __name__ == '__main__':
    main()

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions