[Python-Dev] Allow __enter__() methods to skip the with statement body?

Steven Bethard steven.bethard at gmail.com
Wed Feb 25 19:47:16 CET 2009


On Wed, Feb 25, 2009 at 4:24 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> An interesting discrepancy [1] has been noted when comparing
> contextlib.nested (and contextlib.contextmanager) with the equivalent
> nested with statements.
>
> Specifically, the following examples behave differently if
> cmB().__enter__() raises an exception which cmA().__exit__() then
> handles (and suppresses):
>
>  with cmA():
>    with cmB():
>      do_stuff()
>  # This will resume here without executing "Do stuff"
>
>  @contextlib.contextmanager
>  def combined():
>    with cmA():
>      with cmB():
>        yield
>
>  with combined():
>    do_stuff()
>  # This will raise RuntimeError complaining that the underlying
>  # generator didn't yield
>
>  with contextlib.nested(cmA(), cmB()):
>    do_stuff()
>  # This will raise the same RuntimeError as the contextmanager
>  # example (unsurprising, given the way nested() is implemented)
>
> The problem arises any time it is possible to skip over the yield
> statement in a contextlib.contextmanager based context manager without
> raising an exception that can be seen by the code calling __enter__().

If the problem is just the yield, can't this just be fixed by
implementing contextlib.nested() as a class rather than as a
@contextmanager decorated generator? Or is this a problem with class
based context managers too?

Steve
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


More information about the Python-Dev mailing list