Fix builtin exception handlers to work across modules #951
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.
The builtin exception handler currently doesn't work across modules under clang/libc++ for builtin pybind exceptions like
pybind11::error_already_set
orpybind11::stop_iteration
: under RTLD_LOCAL module loading clang considers each module's exception classes distinct types (this is essentially the same as issue #912). This then means that the base exception translator fails to catch the exceptions and falls through to the genericstd::exception
handler, which completely breaks things likestop_iteration
: only thestop_iteration
of the first module loaded actually works properly. Later modules raise a RuntimeError with no message when their iterators try to signal the end.For example, two modules defined like this exhibit the behaviour under clang++/libc++:
z1.cpp:
z2.cpp:
Python:
results in:
while if you remove
z1
from the import the code runs. (You could also change the order of the import toz2, z1
which lets it run, but would breakz1.IntVector
's iterator).This commit fixes the issue by adding a new exception translator each time the internals pointer is initialized from python builtins: this generally means the internals data was initialized by some other module. (The extra translator(s) are skipped under libstdc++).