Commit Graph

4 Commits

Author SHA1 Message Date
Yuya Nishihara
10370f09a1 test-ctxmanager: stop direct symbol import of mercurial.util 2016-04-05 23:13:52 +09:00
Bryan O'Sullivan
95772fe4ca test-ctxmanager: fix Python 2.6 compatibility problem 2016-01-14 09:31:03 -08:00
Bryan O'Sullivan
506a2494ba util: rename ctxmanager's __call__ method to enter 2016-01-14 09:31:01 -08:00
Bryan O'Sullivan
e1c353db12 util: introduce ctxmanager, to avoid nested try/finally blocks
This is similar in spirit to contextlib.nested in Python <= 2.6,
but uses an extra level of indirection to avoid its inability to
clean up if an __enter__ method raises an exception.

Why add this mechanism?  It greatly simplifies scoped resource
management, and lets us eliminate several hundred lines of try/finally
blocks.  In many of these cases the "finally" is separated from the
"try" by hundreds of lines of code, which makes the connection
between resource acquisition and disposal difficult to follow.

(The preferred mechanism would be the "multi-with" syntax of 2.7+,
but Mercurial can't move to 2.7 for a while.)

Intended use:

>>> with ctxmanager(lambda: file('foo'), lambda: file('bar')) as c:
>>>    f1, f2 = c()

This will open both foo and bar when c() is invoked, and will close
both upon exit from the block.  If the attempt to open bar raises
an exception, the block will not be entered - but foo will still
be closed.
2016-01-11 15:25:43 -08:00