[Python-ideas] Enhanced context managers with ContextManagerExit and None
Kristján Valur Jónsson
kristjan at ccpgames.com
Wed Aug 7 16:23:36 CEST 2013
I just added a patch to the tracker: http://bugs.python.org/issue18677
Here is its' text:
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<http://bugs.python.org/issue5251>.
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.
Cheers,
Kristján
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20130807/bf57926d/attachment-0001.html>
More information about the Python-ideas
mailing list