callback(*args, **kwargs)
else:
callback(*args, **kwargs)
- if getattr(fn, 'stack_context_wrapped', False):
+ if isinstance(fn, (_StackContextWrapper, NoneType)):
return fn
- contexts = _state.contexts
- result = functools.partial(wrapped, fn, contexts)
- result.stack_context_wrapped = True
- return result
+ return _StackContextWrapper(wrapped, fn, _state.contexts)
+@contextlib.contextmanager
+def _nested(*managers):
+ """Support multiple context managers in a single with-statement.
+
+ Copied from the python 2.6 standard library. It's no longer present
+ in python 3 because the with statement natively supports multiple
+ context managers, but that doesn't help if the list of context
+ managers is not known until runtime.
+ """
+ exits = []
+ vars = []
+ exc = (None, None, None)
+ try:
+ for mgr in managers:
+ exit = mgr.__exit__
+ enter = mgr.__enter__
+ vars.append(enter())
+ exits.append(exit)
+ yield vars
+ except:
+ exc = sys.exc_info()
+ finally:
+ while exits:
+ exit = exits.pop()
+ try:
+ if exit(*exc):
+ exc = (None, None, None)
+ except:
+ exc = sys.exc_info()
+ if exc != (None, None, None):
+ # Don't rely on sys.exc_info() still containing
+ # the right information. Another exception may
+ # have been raised and caught by an exit method
+ raise exc[0], exc[1], exc[2]
+