On Sat, Sep 11, 2010 at 3:16 PM, Robert Collins
<[email protected]> wrote:

> This shows a behaviour of context managers that is undesirable for test 
> suites:

I had a hard to debug failure where a context manager was being used
as a test fixture - it did some monkey patching and then cleaned up:

@contextmanager
def with_monkey_patched_thing():
    monkey_patch()
    yield
    revert_monkey_patch()

The end result was the cleanup never got called if the test raised an
exception.  The yield needs to be in a try: finally: block to ensure
cleanup occurs.

@contextmanager
def with_monkey_patched_thing():
    try:
        monkey_patch()
        yield
    finally:
        revert_monkey_patch()




> from contextlib import contextmanager
>
> @contextmanager
> def raiser(message):
>  yield
>  print "cleanup", message
>  raise RuntimeError(message)
>
> with raiser("outer"):
>    with raiser("inner"):
>       print "test code"
>
>
> :!python demo.py
> test code
> cleanup inner
> Traceback (most recent call last):
>  File "demo.py", line 11, in <module>
>    print "test code"
>  File "/usr/lib/python2.6/contextlib.py", line 23, in __exit__
>    self.gen.next()
>  File "demo.py", line 7, in raiser
>    raise RuntimeError(message)
> RuntimeError: inner
>
> In a test suite we want to run all the cleanups, *and* we want to
> report on all the exceptions.



-- 
Stuart Bishop <[email protected]>
http://www.stuartbishop.net/

_______________________________________________
Mailing list: https://launchpad.net/~launchpad-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~launchpad-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to