Source code for being.resources

"""Dynamic resources handling with a global exit stack.

Example:
    >>> from being.resources import manage_resources, register_resource, add_callback
    ... 
    ... 
    ... class Foo:
    ...     def __enter__(self):
    ...         print('Foo.__enter__()')
    ...         return self
    ... 
    ...     def __exit__(self, exc_type, exc_value, traceback):
    ...         print('Foo.__exit__()')
    ... 
    ... 
    ... class Bar:
    ...     def close(self):
    ...         print('Bar.close()')
    ... 
    ... 
    ... with manage_resources():
    ...     foo = Foo()
    ...     register_resource(foo)  # Calls __enter__ here and __exit__ at the end
    ...     bar = Bar()
    ...     add_callback(bar.close)
    Foo.__enter__()
    Bar.close()
    Foo.__exit__()
"""
import contextlib
import warnings
from typing import ContextManager


EXIT_STACK = contextlib.ExitStack()
"""Global exit stack for all resources in being."""

_ALREADY_REGISTERED = set()
"""Set of already registered memory addresses. We can not keep track of already
registered resources by inspecting EXIT_STACK._exit_callbacks because of method
re-mappings.
"""


[docs]def register_resource(resource: ContextManager, duplicates=False): """Register context manager in global being exit stack. Args: resource: Resource to enter into global exit stack. duplicates: Skip duplicate entries. """ addr = id(resource) if addr in _ALREADY_REGISTERED: if duplicates: warnings.warn(f'{resource} already in exit stack!') else: return _ALREADY_REGISTERED.add(addr) EXIT_STACK.enter_context(resource)
#def release_all_resources(): # """Release all registered resources.""" # EXIT_STACK.close()
[docs]def manage_resources(): """Manage all acquired resources in EXIT_STACK.""" return EXIT_STACK
[docs]def add_callback(callback, *args, **kwargs): """Add closing callback to EXIT_STACK. Args: callback: Callback function *args: Variable length argument list for callback. **kwargs: Arbitrary keyword arguments for callback. """ EXIT_STACK.callback(callback, *args, **kwargs)