I have a function which looks something like this:
import contextlib
@contextlib.contextmanager
def special_context(...):
...
yield
...
It is appropriate for this to be used as a context manager, like this:
with special_context(...):
...
... but it is not appropriate for it to be used as a decorator:
# Not OK:
@special_context(...)
def foo():
...
I understand that Python 3.2 added decorator support to contextlib.contextmanager, but in my API it indicates a mistake which causes bugs. I like the ergonomics of contextlib.contextmanager, but I would like to prevent the API from being misused.
Is there a similar construct available (ideally in the standard libs) which would make special_context a context manager, but not a decorator?
Specifically, I want something like this:
@contextmanager_without_decorator
def special_context(...):
...
yield
...
Please help me to find or define contextmanager_without_decorator.
contextlib.ContextDecoratoris the part of the return value of@contextlib.contextmanagerwhich grants the ability to redecorate (in your case,@special_context(...)). The simplest way to prevent this from happening at runtime is to disablecontextlib.ContextDecorator.__call__. The following is one possible implementation of@contextmanager_without_decorator, reproduced by tracing the runtime implementation of@contextlib.contextmanager: