"""This module includes all custom decorators used across paralytics."""
__all__ = [
'force_context_manager'
]
[docs]def force_context_manager(cls):
"""Prevents user from calling objects of decorated classes without using
the `with` statement."""
class Wrapper(object):
original = cls
def __init__(self, *args, **kwargs):
check_exit = getattr(cls, '__exit__', None)
if check_exit is None:
raise NotImplementedError(
'Magic method: `__exit__` must be implemented in the '
'decorated class!'
)
self.args = args
self.kwargs = kwargs
def __enter__(self):
self._wrapped_obj = cls(*self.args, **self.kwargs)
return self._wrapped_obj
def __exit__(self, *args, **kwargs):
self._wrapped_obj.__exit__(*args, **kwargs)
def __getattr__(self, attr):
raise RuntimeError(
'Object of the {0} should only be initialized with the '
'`with` statement. Otherwise, the {0} methods will not '
'be available.'.format(self.original.__name__)
)
Wrapper.__doc__ = cls.__doc__
Wrapper.__name__ = cls.__name__
return Wrapper