[Python-ideas] @contextlib.contextmanager(with_context=True) - passing a context to contextmanager
Nick Coghlan
ncoghlan at gmail.com
Fri Jul 10 09:09:03 CEST 2015
More information about the Python-ideas mailing list
Fri Jul 10 09:09:03 CEST 2015
- Previous message (by thread): [Python-ideas] @contextlib.contextmanager(with_context=True) - passing a context to contextmanager
- Next message (by thread): [Python-ideas] Concurrency Modules
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 10 July 2015 at 07:34, Giampaolo Rodola' <g.rodola at gmail.com> wrote: > > @contextlib.contextmanager(with_context=True) > def wrap_exceptions(ctx): > # ctx is the Process class instance > try: > yield > except EnvironmentError as err: > pid = ctx.pid > name = ctx.name > if err.errno in (errno.ENOENT, errno.ESRCH): > raise NoSuchProcess(pid, name) > if err.errno in (errno.EPERM, errno.EACCES): > raise AccessDenied(pid, name) > raise There isn't anything in this syntax which says to me "designed to be used as a class method decorator", nor in the invocation that says "this CM gets access to the class or instance object" :) The mechanism underlying the context-manager-or-decorator behaviour is actually https://docs.python.org/3/library/contextlib.html#contextlib.ContextDecorator, and that's entirely unaware of both the function being decorated *and* its runtime arguments. This means it is unaware of the details of method invocations as well. If you want a method aware context manager, you'll likely want to write a decorator factory that accepts the relevant CM as a parameter. For example (untested): def with_cm(cm): def decorator(f): @functools.wraps(f) def wrapper(self, *args, **kwargs): with cm(self): return f(self, *args, **kwargs) Used as: class Process: @with_cm(wrap_exceptions) def exe(): ... Regardless, I'd advise against trying to hide the fact that there's an extra step going on in order to make the function being wrapped and/or one or more of its arguments available to the context manager, as that doesn't happen by default. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
- Previous message (by thread): [Python-ideas] @contextlib.contextmanager(with_context=True) - passing a context to contextmanager
- Next message (by thread): [Python-ideas] Concurrency Modules
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-ideas mailing list