[Python-Dev] context manager - generator interaction?

Bob Sidebotham bob.sidebotham at gmail.com
Thu Apr 5 21:54:22 CEST 2007


The interaction shown below feels like a bug, or at least very much a
trap for the unwary. It's some sort of interaction between a context
manager and a generator, both of which can raise StopIteration. The
code is excised from a real application, so it's a bit artificial
looking. Nevertheless, it represents an entirely natural evolution of
some code (whereby the call to a context manager was added deep within
the code). Since it seems to work with open as the context manager,
but not with my own null context manager defined with
context_manager(), it feels like this is probably a bug in
contextmanager().

I did look in the archives, and it's possible this has been raised
before, but I wasn't clear on that. So apologies in advance if this is
already understood.

This is using the stock distribution of python 2.5 on Linux 2.4.

Comments?

Bob Sidebotham

bash-2.05b$ cat test.py
from __future__ import with_statement

def gen():
    return# Should cause stop iteration
    yield # Just to make this a generator, for this example

# This works as expected.
try:
    gen().next() # Should immediately raise StopIteration
except StopIteration:
    print "Part 1: should reach here!"
else:
    print "Part 1: shouldn't reach here!"

# Now try the same thing, but with a context manager wrapping the
generator call.
# This also works as expected.
try:
    with open("/etc/passwd") as pw:
        gen().next()
except StopIteration:
    print "Part 2: should reach here!"
else:
    print "Part 2: shouldn't reach here!"

# Finally, try this with our own home grown null context manager.
# This does not work as expected.
from contextlib import contextmanager

@contextmanager
def ctxt():
    yield

try:
    with ctxt():
        gen().next()
except StopIteration:
    print "Part 3: should reach here!"
else:
    print "Part 3: shouldn't reach here!"

bash-2.05b$ python test.py
Part 1: should reach here!
Part 2: should reach here!
Part 3: shouldn't reach here!
bash-2.05b$


More information about the Python-Dev mailing list