[Python-ideas] Generator-based context managers can't skip __exit__
Ram Rachum
ram at rachum.com
Sun Nov 6 01:02:34 EST 2016
Sorry, I was wrong at quoting the workaround I do, it's actually this:
try:
yield
except GeneratorExit:
raise
except:
cleanup()
raise
else:
cleanup()
This works, but it's ugly! And I basically need to do this to every
generator-based context manager that I want to be able to run just the
`__enter__` of without the `__exit__`. I wish there was a better solution
than including this in my code.
On Sun, Nov 6, 2016 at 7:51 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 6 November 2016 at 14:46, Ram Rachum <ram at rachum.com> wrote:
> > I worked around this problem by adding `except GeneratorExit: raise` in
> my
> > context manager, but that's an ugly solution.
>
> Adding `except GeneratorExit: raise` to a try statement with a finally
> clause won't prevent the finally clause from executing.
>
> Selective non-idempotent cleanup behaviour really isn't a good idea,
> so the language is fighting you for a reason here - the meaning of a
> "finally" clause is that the code it contains *will* get executed, and
> you have to try incredibly hard to keep that from happening since it's
> an implicit part of cleaning up unfinished generators, and we don't
> let you switch the nominal class of generator objects at runtime.
> Indeed, yield inside try/finally was prohibited for years prior to PEP
> 342, as the runtime previously couldn't guarantee that the finally
> clause would actually execute.
>
> If you *don't* want the code to execute unconditionally, then you need
> to be more explicit about when you *do* want it to execute with some
> combination of "except" and "else" clauses. For example:
>
> >>> @contextmanager
> ... def cm():
> ... print("enter")
> ... try:
> ... yield
> ... except Exception:
> ... print("Normal exception, not GeneratorExit,
> KeyboardInterrupt or SystemExit")
> ... else:
> ... print("No exception")
> ...
> >>> cm().__enter__()
> enter
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20161106/c912245f/attachment.html>
More information about the Python-ideas
mailing list