You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Regarding uncaught exceptions in Interpreter.run(), we noted that they are "effectively" propagated into the code where run() was called. To prevent leaking exceptions (and tracebacks) between interpreters, we create a surrogate of the exception and its traceback (see traceback.TracebackException), set it to cause on a new RunFailedError, and raise that.
Raising (a proxy of) the exception directly is problematic since it's harder to distinguish between an error in the run() call and an uncaught exception from the subinterpreter.
Currently uncaught exceptions from Interpreter.run() are stringified and then wrapped in a RunFailedError before being raised in the calling interpreter. This was fine in theory. However, as I've been using subinterpreters in tests I've found that this approach is extremely cumbersome for two reasons:
The solution: "propagate" the original exception and traceback through to the calling interpreter. This is tricky because the exception and traceback must go through the cross-interpreter data machinery. The result would be an exception that matches the original (i.e. a proxy), including a traceback that works as an effective substitute (and any __cause__, etc. set).
Once that is sorted out, we'll set the __cause__ of the raised RunFailedError to the proxy of the original exception. We would end up with tracebacks that look like this:
from PEP 554:
Currently uncaught exceptions from
Interpreter.run()are stringified and then wrapped in aRunFailedErrorbefore being raised in the calling interpreter. This was fine in theory. However, as I've been using subinterpreters in tests I've found that this approach is extremely cumbersome for two reasons:The solution: "propagate" the original exception and traceback through to the calling interpreter. This is tricky because the exception and traceback must go through the cross-interpreter data machinery. The result would be an exception that matches the original (i.e. a proxy), including a traceback that works as an effective substitute (and any
__cause__, etc. set).Once that is sorted out, we'll set the
__cause__of the raisedRunFailedErrorto the proxy of the original exception. We would end up with tracebacks that look like this:Also, how do we get the traceback (e.g. lineno) right?