[Python-Dev] context manager - generator interaction? (original) (raw)
Bob Sidebotham bob.sidebotham at gmail.com
Thu Apr 5 21:54:22 CEST 2007
- Previous message: [Python-Dev] branch is frozen for release of 2.5.1c1 (and 2.5.1)
- Next message: [Python-Dev] context manager - generator interaction?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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$
- Previous message: [Python-Dev] branch is frozen for release of 2.5.1c1 (and 2.5.1)
- Next message: [Python-Dev] context manager - generator interaction?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]