Created
November 1, 2014 16:28
-
-
Save cjerdonek/34a2b255a2fca01d3bae to your computer and use it in GitHub Desktop.
A Python 3.4 module to illustrate a difference between exception handling in generators and context managers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This module illustrates a difference in exception handling between | |
generator functions and context managers. | |
This script should be run with **Python 3.4.2** or higher (which is what | |
it was originally run with). | |
To witness what is illustrated in this module, run the following two | |
commands from the command-line. | |
1) Generator example | |
In this example, notice that the generator does *not* handle the | |
ValueError, despite its try-except. | |
$ python -c "import test_yield; test_yield.test_gen()" | |
Traceback (most recent call last): | |
File "<string>", line 1, in <module> | |
File "/Users/chris_g4/Dev/elections/open-rcv/test_yield.py", line 13, in test_gen | |
raise ValueError("val") | |
ValueError: val | |
2) Context manager example | |
In this example, notice that the context manager *does* handle | |
the ValueError. | |
$ python -c "import test_yield; test_yield.test_manager()" | |
Traceback (most recent call last): | |
File "/Users/chris_g4/Dev/elections/open-rcv/test_yield.py", line 19, in manager | |
yield 1 | |
File "/Users/chris_g4/Dev/elections/open-rcv/test_yield.py", line 24, in test_manager | |
raise ValueError("val") | |
ValueError: val | |
During handling of the above exception, another exception occurred: | |
Traceback (most recent call last): | |
File "<string>", line 1, in <module> | |
File "/Users/chris_g4/Dev/elections/open-rcv/test_yield.py", line 24, in test_manager | |
raise ValueError("val") | |
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/contextlib.py", line 77, in __exit__ | |
self.gen.throw(type, value, traceback) | |
File "/Users/chris_g4/Dev/elections/open-rcv/test_yield.py", line 21, in manager | |
raise TypeError("foo") | |
TypeError: foo | |
""" | |
from contextlib import contextmanager | |
def test_gen(): | |
def gen(): | |
try: | |
yield 1 | |
except ValueError: | |
raise TypeError("foo") | |
for value in gen(): | |
# The generator does not handle this error despite the try-except. | |
raise ValueError("val") | |
def test_manager(): | |
@contextmanager | |
def manager(): | |
try: | |
yield 1 | |
except ValueError: | |
raise TypeError("foo") | |
with manager(): | |
# For the context manager, the error is handled. | |
raise ValueError("val") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment