Skip to content
Foxipa
Code Completion 7 Challenges

Complete the Python context managers code

Practice with statements, implementing context-manager protocols, cleanup, narrow exception suppression, borrowing caller-owned resources with nullcontext(), and closing legacy resources.

Intermediate ~8 min read

Challenge 1

Return self from __enter__ so the as target receives the manager object.

python Your answer
class Tracker:
    def __enter__(self):
        

    def __exit__(self, exc_type, exc_value, traceback):
        return False

with Tracker() as tracker:
    print(tracker is not None)

Press Ctrl⌘Enter to check your answer

Challenge 2

Make __exit__ allow exceptions from the with block to propagate normally.

python Your answer
class SafeBlock:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        

try:
    with SafeBlock():
        raise ValueError("problem")
except ValueError:
    print("propagated")

Press Ctrl⌘Enter to check your answer

Challenge 3

Print a cleanup message from __exit__ so it runs after the block even when the block raises.

python Your answer
class Resource:
    def __enter__(self):
        print("open")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        

try:
    with Resource():
        raise RuntimeError("stop")
except RuntimeError:
    pass

Press Ctrl⌘Enter to check your answer

Challenge 4

Enter both context managers in order using one with statement.

python Your answer
class Mark:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print("enter", self.name)

    def __exit__(self, exc_type, exc_value, traceback):
        print("exit", self.name)


    print("body")

Press Ctrl⌘Enter to check your answer

Challenge 5

Use contextlib.suppress() to ignore only a missing optional dictionary key, then print the stored theme.

python Your answer
from contextlib import suppress

settings = {"theme": "dark"}
with :
    settings.pop("language")
print("theme:", settings["theme"])

Press Ctrl⌘Enter to check your answer

Challenge 6

Use nullcontext so the existing caller-owned stream can be read inside with without being closed by the function.

python Your answer
from contextlib import nullcontext
from io import StringIO

stream = StringIO("caller-owned\n")
with  as active:
    print(active.readline().strip())
print("stream closed:", stream.closed)

Press Ctrl⌘Enter to check your answer

Challenge 7

Use contextlib.closing() to ensure the reader is closed when the with block ends.

python Your answer
from contextlib import closing

class LegacyReader:
    def __init__(self):
        self.closed = False

    def read(self):
        return "record"

    def close(self):
        self.closed = True

reader = LegacyReader()
with  as active:
    print(active.read())
print("closed:", reader.closed)

Press Ctrl⌘Enter to check your answer