This repository has been archived by the owner on Jul 17, 2024. It is now read-only.
feat: Add file and line numbers to exception traceback #28
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
CPython does not expose any sane way to set the traceback
of an exception that does not orginate from a CPython
exception. In particular, traceback must be an
internal Traceback type, and that Traceback type
cannot be constructed without using internal frame
and code types, which also cannot be constructed.
To get around this, we exploit the traceback module,
which does not care about types and only care about
interfaces. This allow us to use our own fake frame
and code classes that match their interface.
We exploit object.new to create an instance of
TracebackException without calling its constructor,
and set all its fields manually
To set the stack field, we use StackSummary.from_list.
with the Java traceback.
Python 3.10 has a quirk: it calls RERAISE in
the finally block corresponding to an except
block. That finally immediately calls RERAISE,
but TOS is a type, so that exception loses both
it cause and message. So work around this,
we deviate a bit from how the code apparently
works
<block (3 items)> traceback, exeception, exception
instead of
<block (3 items)> traceback, exeception, type
instead of issubclass
This works since Python pops off all these values when
actually entering the code for an except block, and
JUMP_IF_NOT_EXEC_MATCH is the only opcode that can
be encountered.