Files
RustPython/vm
Daniel Chiquito 85c427b842 Reset exception in WithCleanupFinish (#5203)
Context managers have an `__exit__` function that returns a boolean-like
object. If the object is truthy, then exceptions are suppressed.

If an exception was thrown while resolving that boolean, it would leak
and live on in the error stack, getting tacked on to all future
exceptions. This caused several mysterious test failures which would
only trigger after this very specific event was tested in `test_with`.

The solution is to move a call to `vm.set_exception()` before
attempting the `try_to_bool()` which threw the error.

Minimal example to reproduce the bug:
```py
import sys
import traceback

class cm(object):
    def __init__(self):
        pass

    def __enter__(self):
        return 3

    def __exit__(self, a, b, c):
        class Bool:
            def __bool__(self):
                1 // 0
        return Bool()

try:
    with cm():
        raise Exception("Should NOT see this")
except ZeroDivisionError:
    print("exception caught, as expected")

print("There should now be no exception")
traceback.print_exc()
print(sys.exc_info())
```
2024-03-22 00:12:01 +09:00
..
2018-07-07 17:14:45 +02:00
2023-12-28 23:44:47 +09:00