contextlib.nested()

Robert Lehmann stargaming at gmail.com
Thu Nov 6 05:43:25 EST 2008


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



More information about the Python-list mailing list