New issue 3096: PyErr_SetExcInfo(NULL, NULL, NULL) does not fully clear current
thread exception context
https://bitbucket.org/pypy/pypy/issues/3096/pyerr_setexcinfo-null-null-null-does-not
Kirill Smelkov:
Hello up there. Please consider the following example:
\(mysys.pyx\)
```python
# cython: language_level=3
cdef extern from "Python.h":
struct PyObject
void PyErr_SetExcInfo(PyObject*, PyObject*, PyObject*)
# exc_clear is like sys.exc_clear() on py2 - it clears current thread's caught
exception state.
def exc_clear():
PyErr_SetExcInfo(NULL, NULL, NULL)
```
\(mysys\_test.py\)
```
import mysys
def recover():
mysys.exc_clear()
def main2():
try:
raise RuntimeError('aaa')
finally:
recover()
raise RuntimeError('bbb')
def main():
main2()
"""
try:
main2()
except Exception as e:
print(repr(e))
print('__cause__:', e.__cause__)
print('__context__:', e.__context__)
print(dir(e))
"""
if __name__ == '__main__':
main()
```
When run with CPython-3.7 it prints only ‘bbb’:
```
$ python3.7 mysys_test.py
Traceback (most recent call last):
File "mysys_test.py", line 27, in <module>
main()
File "mysys_test.py", line 15, in main
main2()
File "mysys_test.py", line 11, in main2
raise RuntimeError('bbb')
RuntimeError: bbb
```
but when run with PyPy3.6-7.2 it prints both ‘bbb’ _**and**_ ‘aaa’:
```
$ pypy3 mysys_test.py
Traceback (most recent call last):
File "mysys_test.py", line 8, in main2
raise RuntimeError('aaa')
RuntimeError: aaa
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "mysys_test.py", line 27, in <module>
main()
File "mysys_test.py", line 15, in main
main2()
File "mysys_test.py", line 11, in main2
raise RuntimeError('bbb')
RuntimeError: bbb
```
If I uncomment printing code in main, it shows that under cpython
`e.__context__ is None` while under pypy `e.__context__` points to
`RuntimeError('aaa')`.
If I put `mysys.exc_clear()` directly into `finally` block without doing it
through `recover()` call, the bug goes away.
```
$ pypy3 --version
Python 3.6.9 (5da45ced70e5, Oct 09 2019, 19:12:54)
[PyPy 7.2.0 with GCC 6.2.0 20160901]
```
The bug also happens with pypy-7.0 and 7.1.
The bug was caught while testing pygolang on pypy3 and is minimal example of
what happens there in `defer` and `recover` functionality.
Thanks beforehand,
Kirill
/cc @{557058:7cb88866-fb18-487e-a2dc-b19de69f5f0b}
_______________________________________________
pypy-issue mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-issue