New submission from Nick Coghlan:

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!

```

----------
keywords: 3.5regression
messages: 288793
nosy: ncoghlan
priority: normal
severity: normal
stage: test needed
status: open
title: contextlib.contextmanager may incorrectly unchain RuntimeError
type: behavior
versions: Python 3.5, Python 3.6, Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue29692>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to