Handling instances of a context manager inside another context manager

contextmanager, python

Solution

If you can use the `@contextlib.contextmanager` decorator your life gets a lot easier:

import contextlib

@contextlib.contextmanager
def internal_cm():
    try:
        print "Entering internal_cm"
        yield None
        print "Exiting cleanly from internal_cm"
    finally:
        print "Finally internal_cm"


@contextlib.contextmanager
def external_cm():
    with internal_cm() as c:
        try:
            print "In external_cm_f", c
            yield [c]
            print "Exiting cleanly from external_cm_f", c
        finally:
            print "Finally external_cm_f", c


if "__main__" == __name__:
    with external_cm():
        print "Location A"
    print
    with external_cm():
        print "Location B"
        raise Exception("Some exception occurs!!")

Problem

How should a context manager created inside another context manager be handled in Python? Example: suppose you have class `A` that acts as a context manager, and class `B` that also acts as a context manager. But class `B` instances will have to instantiate and use an instance of class `A`. I've gone through PEP 343 and this is the solution I thought of: ``` class A(object): def __enter__(self): # Acquire some resources here return self def __exit__(seplf, exception_type, exception, traceback): # Release the resources and clean up pass class B(object): def __init__(self): self.a = A() def __enter__(self): # Acquire some resources, but also need to "start" our instance of A self.a.__enter__() return self def __exit__(self, exception_type, exception, traceback): # Release the resources, and make our instance of A clean up as well self.a.__exit__(exception_type, exception, traceback) ``` Is this the correct approach? Or am I missing some gotchas?

Original source

Related problems