[Python-ideas] Generator-based context managers can't skip __exit__

Ram Rachum ram at rachum.com
Sun Nov 6 00:46:40 EDT 2016


Hi everyone,

Here is a simplification of a problem that's been happening in my code:

import contextlib

@contextlib.contextmanager
def f():
    print('1')
    try:
        yield
    finally:
        print('2')


g = f()
g.__enter__()


This code prints 1 and then 2, not just 1 like you might expect. This is
because when the generator is garbage-collected, it gets `GeneratorExit`
sent to it.

This has been a problem in my code since in some instances, I tell a
context manager not to do its `__exit__` function. (I do this by using
`ExitStack.pop_all()`. However the `__exit__` is still called here.

I worked around this problem by adding `except GeneratorExit: raise` in my
context manager, but that's an ugly solution.

Do you think that something could be done so I won't have to add  `except
GeneratorExit: raise` to each context manager to get the desired behavior?


Thanks,
Ram.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20161106/eba76434/attachment-0001.html>


More information about the Python-ideas mailing list