
fwiw, I believe you could write a version of nested that generates the above code based on the parameters but I believe it'd be disgustingly slow...
@contextmanager def slow_nested(*args): code_lines = [] vars = [] code_lines.append('@contextmanager') code_lines.append('def _nested(*args):') for idx in xrange(len(args)): vars.append('c%d' % idx) code_lines.append('%swith args[%d] as %s:' % (' '*(idx+1), idx, vars[-1])) code_lines.append('%syield %s' % (' '*(len(args)+1), ','.join(vars))) code = '\n'.join(code_lines) print 'CODE:\n', code exec(code) yield _nested(*args)
Unfortunately, that doesn't help: the problem is the fact that the arguments to nested() are evaluated *before* the call to nested() itself. A version with lazily evaluated arguments (i.e. accepting zero-argument callables that create the context managers instead of accepting the context managers themselves) could do the trick, but that then becomes enough of a pain to use that it wouldn't offer much benefit over writing a dedicated context manager. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------