On Thu, 06 Nov 2008 01:02:34 -0800, brasse wrote: > Hello! > > I have been running in to some problems when using contextlib.nested(). > My problem arises when using code similar to this: > > from __future__ import with_statement > > from contextlib import nested > > class Foo(object): > > def __init__(self, tag, fail=False): > print 'ctor', tag > self.tag = tag > if fail: > raise Exception() > > def __enter__(self): > print '__enter__', self.tag > return self > > def __exit__(self, *args): > print '__exit__', self.tag > > with nested(Foo('a'), Foo('b', True)) as (a, b): > print a.tag > print b.tag > > Here the construction of b fails which in turn means that the > contextmanager fails to be created leaving me a constructed object (a) > that needs to be deconstructed in some way. I realize that nested() is > in a tight spot here to do anything about it since it doesn't exist. > This behavior makes it hard for me to use the with statement (using > nested()) the way I want. > > Has anyone else been running in to this? Any tips on how to handle > multiple resources?
Your problem does not seem to be connected to context managers. The error occurs before calling `contextlib.nested` at all:: >>> foo = [Foo('a')] ctor a >>> with nested(*foo) as a: print a ... __enter__ a [<__main__.Foo object at 0x7fbc29408b90>] __exit__ a >>> foo = [Foo('a'), Foo('b', True)] ctor a ctor b Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 7, in __init__ raise Exception() Exception If you need to deconstruct object `a` from your example, your staging is probably broken. Allocate the resource in `__init__` but only go live just in `__enter__`. If you do not enter the context, then, you won't need to deconstruct it as well. HTH, -- Robert "Stargaming" Lehmann -- http://mail.python.org/mailman/listinfo/python-list