contextlib.contextmanager and try/finally

2012-01-11 Thread johannh
I'm trying to write a context manager to handle database connections, under the 
principle that I should not rely on CPython's reference-counting semantics to 
clean up scarce resources, like connections.

I wrote:

@contexlib.contextmanager
def ensure_connection(con=None):
con_created = False
if con is None:
con_created, con = True, make_connection()
try:
yield con
finally:
if con_created:
con.close()

However, then I read the following paragraph from PEP-343:

Note that we're not guaranteeing that the finally-clause is
executed immediately after the generator object becomes unused,
even though this is how it will work in CPython.  This is similar
to auto-closing files: while a reference-counting implementation
like CPython deallocates an object as soon as the last reference
to it goes away, implementations that use other GC algorithms do
not make the same guarantee.  This applies to Jython, IronPython,
and probably to Python running on Parrot.

That suggests that I cannot rely on the contextlib.contextmanager decorator to 
ensure that the connection is closed and would have to write my own object with 
__enter__ and __exit__ methods to guarantee this.

Is this understanding accurate?  If so, could someone illustrate why this is 
so? 

Thanks,
Johann
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: contextlib.contextmanager and try/finally

2012-01-11 Thread johannh
On Wednesday, January 11, 2012 11:20:19 AM UTC-6, Ian wrote:
> 
> Second, I believe that passage is not referring to the contextmanager
> decorator specifically, but more generally to the changes that were
> made to allow generators to yield from within a try-finally construct
> (previously this would have been illegal syntax, since there was no
> way to guarantee the finally block would be performed).

Thanks.  You and Robert have shown me the light.  That paragraph was talking 
about the finalization that happens to a suspended generator when it is GC'd.  
Meanwhile, the contextmanager decorator ensures that its generator is run all 
the way through, so it would never be left in a suspended state, so its 
GC/finalization semantics are irrelevant. (Please correct, if wrong.)

(Neil: I understood that it created a context manager object, but I had been 
reading the quoted paragraph to mean that by going through a generator the 
decorator was re-introducing a dependency on GC time.  But I was wrong.)

Regards,
Johann
-- 
http://mail.python.org/mailman/listinfo/python-list