register_exception does not work after re-initializing an embedded interpreter
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Consider the following example, which adds an exception type SomeException to module foo , re-initializes the interpreter, and tries to do the same again:
PYBIND11_EMBEDDED_MODULE(foo, mod) { /* Nothing */ }
struct SomeException : public std::runtime_error {};
int main() {
{
pybind11::scoped_interpreter interpreter;
auto foo = pybind11::module::import("foo");
pybind11::register_exception<SomeException>(foo, "SomeException");
assert(!foo.attr("SomeException").is_none());
}
{
pybind11::scoped_interpreter interpreter;
auto foo = pybind11::module::import("foo");
pybind11::register_exception<SomeException>(foo, "SomeException");
assert(!foo.attr("SomeException").is_none()); // This throws an exception
}
}
The second call to register_exception fails silently, because the first pybind11::exception object is still alive due to its static lifetime in pybind11::detail::get_exception_object, making register_exception think that the type has already been added.
The same behavior can be observed when trying to add the same exception type to multiple modules:
PYBIND11_EMBEDDED_MODULE(foo, mod) { /* Nothing */ }
PYBIND11_EMBEDDED_MODULE(bar, mod) { /* Nothing */ }
struct SomeException : public std::runtime_error {};
int main() {
pybind11::scoped_interpreter interpreter;
auto foo = pybind11::module::import("foo");
pybind11::register_exception<SomeException>(foo, "SomeException");
pybind11::register_exception<SomeException>(bar, "SomeException");
assert(!foo.attr("SomeException").is_none());
assert(!bar.attr("SomeException").is_none()); // This throws an exception
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in include/pybind11/pybind11.h at detail::get_exception_object, which the issue identifies as retaining the exception object across interpreter lifetimes. Reproduce the examples for interpreter re-initialization and registration in multiple modules; done means both calls expose SomeException without throwing or silently failing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100