[Python-ideas] A real limitation of contextlib.nested()

Nick Coghlan ncoghlan at gmail.com
Sun Mar 15 11:24:53 CET 2009

> 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.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list