This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author kristjan.jonsson
Recipients kristjan.jonsson
Date 2013-08-07.14:22:03
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1375885327.18.0.790620363467.issue18677@psf.upfronthosting.co.za>
In-reply-to
Content
A proposed patch adds two features to context managers:

1)It has always irked me that it was impossible to assemble nested context managers in the python language. See issue #5251.
The main problem, that exceptions in __enter__ cannot be properly handled, is fixed by introducing a new core exception, ContextManagerExit.  When raised by __enter__(), the body that the context manager protects is skipped.  This exception is in the spirit of other semi-internal exceptions such as GeneratorExit and StopIteration.  Using this exception, contextlib.nested can properly handle the case where the body isn't run because of an internal __enter__ exception which is handled by an outer __exit__.

2) The mechanism used in implementing ContextManagerExit above is easily extended to allowing a special context manager: None.  This is useful for having _optional_ context managers.  E.g. code like this:
    with performance_timer():
        do_work()

    def performance_timer():
        if profiling:
            return accumulator
        return None

None becomes the trivial context manager and its __enter__ and __exit__ calls are skipped, along with their overhead.

This patch implements both features.
In addition, it:
1) reintroduces contextlib.nested, which is based on nested_delayed
2) introduces contextlib.nested_delayed, which solves the other problem with previous versions of nested, that an inner context manager expression shouldn't be evaluated early.  contextlib.nested evaluates callables returning context managers, rather than managers directly.
3) Allows contextlib.contextmanager decorated functions to not yield, which amounts to skipping the protected body (implicitly raising ContextManagerExit)
4) unittests for the whole thing.

I'll introduce this stuff on python-ideas as well.
History
Date User Action Args
2013-08-07 14:22:07kristjan.jonssonsetrecipients: + kristjan.jonsson
2013-08-07 14:22:07kristjan.jonssonsetmessageid: <1375885327.18.0.790620363467.issue18677@psf.upfronthosting.co.za>
2013-08-07 14:22:07kristjan.jonssonlinkissue18677 messages
2013-08-07 14:22:06kristjan.jonssoncreate