Hagen Fürstenau wrote: > I'm proposing to add an iterator version of "nested" to contextlib > (possibly called "inested"), which takes an iterable of context managers > instead of a variable number of parameters. The implementation could be > taken over from the present "nested", only changing "def > nested(*managers)" to "def inested(managers)". > > This has the advantage that an iterator can be passed to "inested", so > that each context managers is created in the context of all previous > ones, which was one of the reasons for introducing the multi-with > statement in the first place. "contextlib.inested" would therefore be > the generalization of the multi-with statement to a variable number of > managers (and "contextlib.nested" would stay deprecated).
The semantic change actually needed to make nested() more equivalent to the multi-with statement is for it to accept zero-argument callables that create context managers as arguments rather than pre-created context managers. Rather than changing the name of the function, this could be done by inspecting the first argument for an "__enter__" method. If it has one, use the old semantics (and issue a DeprecationWarning as in 3.1). Otherwise, use the proposed new semantics. However, the semantic equivalence still won't be complete as nested() currently has no way of matching the multi-with behaviour of allowing outer context managers to suppress exceptions raised by the constructors or __enter__ methods of inner context managers. Attempting to do so will result in a RuntimeError as the contextlib.contextmanager wrapper complains that the generator implementing nested() didn't yield. The further enhancement needed to address that would be to tweak nested() to raise a custom exception in that case (e.g. ContextSkipped) and provide an "allowskip" context manager that just catches and suppresses that specific exception: i.e. @contextmanager def allowskip(): try: yield except ContextSkipped: pass with allowskip(), nested(*cm_factories): # Do something I suggest putting an RFE on the tracker for this. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia --------------------------------------------------------------- _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com