Timefold Solver is an AI constraint solver for Python to optimize the Vehicle Routing Problem, Employee Rostering, Maintenance Scheduling, Task Assignment, School Timetabling, Cloud Optimization, Conference Scheduling, Job Shop Scheduling, Bin Packing and many more planning problems.
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
After finally branch is taken, stack is
traceback, exeception, exception
instead of
traceback, exeception, type
JUMP_IF_NOT_EXEC_MATCH is now an instanceof
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.
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
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.