Package: contexter
Contexter is a full replacement of thecontextlib[1]standard library module. It comes with more features, a nicer API and full support for Python 2.5 up to 3.x from a single source file.To keep it short: Contexter allows you to nest and stack context managers in an easy and intuitive way.Enough talk, let’s see an example:''' Copy the content of one file to another
     and protect everything with a lock. '''withContexter(lock)asctx:in_file=ctx<<open('a.txt')out_file=ctx<<open('b.txt','w')out_file.write(in_file.read())Look at that. It’s beautiful, isn’t it? Let me explain: You callContexter()with any number of context managers as arguments and later attach additional managers with the neatvalue = ctx << thingsyntax. That’s it. Only one level of indentation, no matter how many managers you need.Just for comparison:# Python 2.5 and 2.6withlock:withopen('a.txt')asin_file:withopen('b.txt','w')asout_file:out_file.write(in_file.read())# Starting with Python 2.7 and 3.2withlock,open('a.txt')asin_file,open('b.txt','w')asout_file:out_file.write(in_file.read())# Deprecated since Python 2.7 and 3.2withcontextlib.nested(lock,open('a.txt'),open('b.txt','w'))asvalues:in_file,out_file=valuesout_file.write(in_file.read())# Since Python 3.3 (not backported to 2.7)withcontextlib.ExitStack()asstack:stack.enter_context(lock)in_file=stack.enter_context(open('a.txt'))out_file=stack.enter_context(open('b.txt','w'))out_file.write(in_file.read())Replacingcontextlib.nested[2]You can useContexter(*managers)as a drop-in replacement forcontextlib.nested(*managers), just without theconfusing error prone quirks mentioned in the official documentation.Replacingcontextlib.closing[3]Just forget about it. Contexter turns close-able objects into context managers automatically.Replacingcontextlib.ExitStack[4]Contexter offeres everythingcontextlib.ExitStackdoes (and more). If you want a drop-in replacement that also works for Python 2.x and 3.2, you can use our backportedExitStack, a subclass ofContexterthat is API compatible to the contextlib variant.Replacing everything else from contextlibIf you really want to stick with the standard API, you can. Contexter implements all public APIs from contextlib and backports new features as soon as they are introduced.More examples:Contexter keeps track of the results of all invoked context managers. You can access the results later and don’t have to unpack them all at the beginning.withContexter(open('a.txt'),open('b.txt','w'))asctx:in_file,out_file=ctx.values()assertctx.value(0)isin_fileassertctx[0]isin_fileassertctx[0:2]==[in_file,out_file]assertlen(ctx)==2If you don’t like the<<syntax, there is a method that does the same.withContexter()asctx:in_file=ctx<<open('a.txt')out_file=ctx.append(open('b.txt','w'))Contexter contexts are nestable. Each level of nesting maintains its own stack of context managers and result values. This allows you to control the lifetime of contexts very precisely.withContexter()asctx:out_file=ctx<<open('b.txt','w')withctx:in_file=ctx<<open('a.txt')copy_data(in_file,out_file)assertin_file.closed==Trueassertout_file.closed==FalseLinks[1]http://docs.python.org/3/library/contextlib.html[2]http://docs.python.org/2/library/contextlib.html#contextlib.nested[3]http://docs.python.org/3/library/contextlib.html#contextlib.closing[4]http://docs.python.org/3/library/contextlib.html#contextlib.ExitStack