A "scopeguard" for Python

Mike Kent mrmakent at gmail.com
Fri Mar 5 17:29:59 CET 2010


On Mar 4, 8:04 pm, Robert Kern <robert.k... at gmail.com> wrote:

> No, the try: finally: is not implicit. See the source for
> contextlib.GeneratorContextManager. When __exit__() gets an exception from the
> with: block, it will push it into the generator using its .throw() method. This
> raises the exception inside the generator at the yield statement.

Wow, I just learned something new.  My understanding of context
managers was that the __exit__ method was guaranteed to be executed
regardless of how the context was left.  I have often written my own
context manager classes, giving them the __enter__ and __exit__
methods.  I had mistakenly assumed that the @contextmanager decorator
turned a generator function into a context manager with the same
behavior as the equivalent context manager class.  Now I learn that,
no, in order to have the 'undo' code executed in the presence of an
exception, you must write your own try/finally block in the generator
function.

This raises the question in my mind: What's the use case for using
@contextmanager rather than wrapping your code in a context manager
class that defines __enter__ and __exit__, if you still have to
manager your own try/finally block?



More information about the Python-list mailing list