473,387 Members | 3,750 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

contextlib.nested()

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?

Regards,
Mattias
Nov 6 '08 #1
7 1961
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?
I don't fully understand this. Why is in need to be deconstructed? Sure, the
object is created, but whatever is actually done on initialization which is
non-trivial should of course to the __enter__-method - which isn't called.

So, a falls out of a scope & gets GC'ed. What else do you expect to happen?

Diez
Nov 6 '08 #2
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
Nov 6 '08 #3
On Nov 6, 11:43*am, Robert Lehmann <stargam...@gmail.comwrote:
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
Diez, Robert,

OK. The practice of "going live" or doing non-trivial initialization
in __enter__ is new to me. I'm new to Python with a C++ background, so
that shouldn't be a surprise. :-)

Ideally I would like to put all initialization in __init__ since then
I would be able to use my object right after constructing it, without
having to use it in a with statement. The reason I'm struggling with
this is probably my C++ background. I'm rally accustomed to design
with RAII in mind. Acquiring all resources in the ctor and releasing
all resources in the dtor is *really* handy.

If you had a class that wanted to acquire some external resources that
must be released at some point, how would you rewrite the code from my
example?

:.:: mattias
Nov 6 '08 #4
Diez, Robert,
>
OK. The practice of "going live" or doing non-trivial initialization
in __enter__ is new to me. I'm new to Python with a C++ background, so
that shouldn't be a surprise. :-)

Ideally I would like to put all initialization in __init__ since then
I would be able to use my object right after constructing it, without
having to use it in a with statement. The reason I'm struggling with
this is probably my C++ background. I'm rally accustomed to design
with RAII in mind. Acquiring all resources in the ctor and releasing
all resources in the dtor is *really* handy.
Yes, but this is a C++ idiom that does not translate well to python's
GC-based approach. Which is the *exact* reason why contexts have been
created in the first place.
If you had a class that wanted to acquire some external resources that
must be released at some point, how would you rewrite the code from my
example?
If you *can*, use a context. Use __enter__ and __exit__. Try really hard to
use it that way.

If not - create a specific finalize-method or some such, and try not to
forget to call that. Potentially with an atexit-handler or some such.

the problem is that python can't guarantee that a __del__-method is invoked
at all, and *if* it is, it might find other stuff being released already
that it relies upon - e.g. imported modules being freed & not known
anymore.

Diez
Nov 6 '08 #5
On Nov 6, 5:45*pm, "Diez B. Roggisch" <de...@nospam.web.dewrote:
If you had a class that wanted to acquire some external resources that
must be released at some point, how would you rewrite the code from my
example?

If you *can*, use a context. Use __enter__ and __exit__. Try really hard to
use it that way.
My case becomes something like 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
self.fail = fail

def __enter__(self):
if self.fail:
print 'fail', self.tag
raise Exception()
print '__enter__ acquire resource', self.tag
return self

def __exit__(self, *args):
print '__exit__ release resource', self.tag

with nested(Foo('a'), Foo('b', True)) as (a, b):
print a.tag
print b.tag

When using Foo objects in a with statement this works good for me. But
what if I want to use Foo objects as members in a class for example?
Since we now must contruct an instance of Foo in two stages the code
becomes less than ideal.

def __init__(self):
self.x = Foo()
self.x.__enter__()

Perhaps there is no way to write classes that fits neatly into all (or
even these two) usage scenarios?
If not - create a specific finalize-method or some such, and try not to
forget to call that. Potentially with an atexit-handler or some such.
It seems to me that I have to use the with statement (or some try-
finally construct) to be able to release all resources when my code
throws exceptions(). Just remembering to call close/finalize/destroy
will not be enough.

:.:: mattias
Nov 7 '08 #6
brasse wrote:
with nested(Foo('a'), Foo('b', True)) as (a, b):
Â* Â* print a.tag
Â* Â* print b.tag
If been watching this thread for a while, and I think that your problems
will go away if you write actual nested with-blocks:

with Foo("a") as a:
with Foo("b") as b:
print a.tag
print b.tag

Why look for a complex solution if there is a simple one?

Peter
Nov 7 '08 #7
On Nov 7, 10:33*am, Peter Otten <__pete...@web.dewrote:
brasse wrote:
with nested(Foo('a'), Foo('b', True)) as (a, b):
* * print a.tag
* * print b.tag

If been watching this thread for a while, and I think that your problems
will go away if you write actual nested with-blocks:

with Foo("a") as a:
* * with Foo("b") as b:
* * * * print a.tag
* * * * print b.tag

Why look for a complex solution if there is a simple one?
That works great if you are only working with two objects. It gets a
bit uglier when you need to use three or more objects. I'm just trying
to figure out if there is some kind of best practice in the Python
community that works well (even with more than two objects) for the
two usage scenarios I have described.

:.:: mattias
Nov 7 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Andy Baker | last post by:
Hi there, I'm learning Python at the moment and trying to grok the thinking behind it's scoping and nesting rules. I was googling for nested functions and found this Guido quote:...
3
by: Erik Bongers | last post by:
Hi, Nested classes only seem to be able to access static members of the surrounding class : class SurroundingClass { public: class InnerClass { public:
6
by: B0nj | last post by:
I've got a class in which I want to implement a property that operates like an indexer, for the various colors associated with the class. For instance, I want to be able to do 'set' operations...
8
by: Robert W. | last post by:
I've almost completed building a Model-View-Controller but have run into a snag. When an event is fired on a form control I want to automatically updated the "connnected" property in the Model. ...
1
by: Tomas Sieger | last post by:
Hi all, I'm in doubt with the following code: class Base { public: class Nested {}; }; class Derived:public Base { public: class Nested {
77
by: Peter Olcott | last post by:
http://www.tommti-systems.de/go.html?http://www.tommti-systems.de/main-Dateien/reviews/languages/benchmarks.html The above link shows that C# is 450% slower on something as simple as a nested loop....
1
by: Paul Rubin | last post by:
it looks like contextlib.closing fails to be idempotent, i.e. wrapping closing() around another closing() doesn't work. This is annoying because the idea of closing() is to let you use legacy...
3
by: jdurancomas | last post by:
Dear all, I'm trying to declare the operator++ to a nested class. The nested class is not template but the container it is. The code used in teh sample program is included bellow: ...
1
by: Neal Becker | last post by:
http://www.python.org/doc/2.5.2/lib/module-contextlib.html has this example: from contextlib import contextmanager @contextmanager def tag(name): print "<%s>" % name yield print "</%s>" %...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.