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 <[email protected]> wrote:
> On 6 November 2016 at 14:46, Ram Rachum <[email protected]> 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 | [email protected] | Brisbane, Australia
>
_______________________________________________
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/