Author ncoghlan
Recipients ncoghlan
Date 2017-03-02.10:11:34
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1488449495.24.0.0941910154043.issue29692@psf.upfronthosting.co.za>
In-reply-to
Content
As part of PEP 479, an extra check was added to contextlib._GeneratorContextManager to avoid getting confused when a StopIteration exception was raised in the body of the with statement, and hence thrown into the generator body implementing the context manager.

This extra check should only be used when the passed in exception is `StopIteration`, but that guard is currently missing, so it may unchain arbitrary RuntimeError exceptions if they set their `__cause__` to the originally passed in value.

Compare the current contextmanager behaviour:

```
>>> from contextlib import contextmanager
>>> @contextmanager
... def chain_thrown_exc():
...     try:
...         yield
...     except Exception as exc:
...         raise RuntimeError("Chained!") from exc
... 
>>> with chain_thrown_exc():
...     1/0
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
```

To the expected inline behaviour:

```
>>> try:
...     1/0
... except Exception as exc:
...     raise RuntimeError("Chained!") from exc
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Chained!

```
History
Date User Action Args
2017-03-02 10:11:35ncoghlansetrecipients: + ncoghlan
2017-03-02 10:11:35ncoghlansetmessageid: <1488449495.24.0.0941910154043.issue29692@psf.upfronthosting.co.za>
2017-03-02 10:11:35ncoghlanlinkissue29692 messages
2017-03-02 10:11:34ncoghlancreate