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 pypy-issue@python.org https://mail.python.org/mailman/listinfo/pypy-issue