In [37]:
class MockDatabase(object):
    def __init__(self):
        self.open = False
    @property
    def isopen(self):
        return self.open
    def connect(self):
        assert not self.isopen, 'already open'
        print 'opening mock database'
        self.open = True
    def close(self):
        assert self.isopen, 'already closed'
        print 'closing mock database'
        self.open = False
    def execute(self, command):
        assert self.isopen, 'not open'
        print 'executed %s' % command

In [38]:
db = MockDatabase()
db.connect()
db.execute('my command')


opening mock database
executed my command

In [30]:
class MockDatabaseConnection(object):
    def __enter__(self):
        print 'entering'
        self.db = MockDatabase()
        self.db.connect()
        return self.db
    def __exit__(self, *args):
        print 'exiting'
        self.db.close()
    def do_something(self):
        print 'doing something'

In [41]:
with MockDatabaseConnection() as db:
    db.execute('some command')
    raise ValueError('something bad happened')
    db.execute('some other command')


entering
opening mock database
executed some command
exiting
closing mock database
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-41-48b242465650> in <module>()
      1 with MockDatabaseConnection() as db:
      2     db.execute('some command')
----> 3     raise ValueError('something bad happened')
      4     db.execute('some other command')

ValueError: something bad happened

In [47]:
from contextlib import contextmanager

@contextmanager
def mock_db_connection():
    db = MockDatabase()
    db.connect()
    try:
        yield db
    except:
        pass
    db.close()

In [ ]:


In [48]:
with mock_db_connection() as db:
    db.execute('some command')
    raise ValueError('something bad happened')
    db.execute('some other command')


opening mock database
executed some command
closing mock database

In [50]:
with open('foo.txt','w') as f:
    f.write('the contents of foo.txt')