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