From: "andrew cooke" <andrew@...>
Date: Sun, 27 Apr 2008 19:50:32 -0400 (CLT)
This is quite cute - it's similar to what I've seen in Scheme/Lisp and, I
think, Haskell, where you can specify a "finally" action:
from __future__ import with_statement
from myapp.context import close, dispose
[...]
class ...
def _create_database(self):
(db, url) = split_database(self._url)
log.debug(_('Creating database %s') % db)
try:
with dispose(self._create_engine(url)) as engine:
with close(engine.connect()) as cnx:
# can't use text here as it quotes strings
cnx.execute('create database %s' % db)
except ...
Note the "with close(...)" and "with dispose(...)" which call those
methods (close(), dispose()) on the associated objects at the end of the
block.
myapp.context:
from acooke.context import no_args
def close(client):
return no_args(client, 'close')
def dispose(client):
return no_args(client, 'dispose')
acooke.context:
class Context(object):
def __init__(self, client=None, on_entry=lambda x: x,
on_exit=lambda (x, tp, vl, tb): False, **kargs):
super(Context, self).__init__(**kargs)
self._client = client
self._on_entry = on_entry
self._on_exit = on_exit
def __enter__(self):
return self._on_entry(self._client)
def __exit__(self, tp, vl, tb):
return self._on_exit(self._client, tp, vl, tb)
def no_args(client, attr):
def f(x, tp, vl, tb):
getattr(x, attr)()
return False
return Context(client=client, on_exit=f)
Andrew