-
I am trying to replicate the exception handling described here: Unfortunately, this hangs on my setup (Mac OS 13.3.1, arm64, pybind11 2.10.4). If I don't try to handle the exception, I get an expected crash:
Here is the full code to replicate ( #include <pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
int main() {
// Calling the following directly leads to the exepected
// terminating due to uncaught exception of type
// pybind11::error_already_set: ModuleNotFoundError:
// No module named 'fakemodule'
//py::scoped_interpreter guard{};
//py::exec("import fakemodule");
try {
std::cout << "Starting import test" << std::endl;
py::scoped_interpreter guard{};
// The following hangs
py::exec("import fakemodule");
std::cout << "Done import test" << std::endl;
return EXIT_SUCCESS;
} catch (py::error_already_set& e) {
std::cout << "Caught py::error_already_set exception in main"
<< e.what() << std::endl;
return EXIT_FAILURE;
} catch (const std::exception& e) {
// standard exceptions
std::cout << "Caught std::exception in main: " << e.what() << std::endl;
return EXIT_FAILURE;
} catch (...) {
// everything else
std::cout << "Caught unknown exception in main" << std::endl;
return EXIT_FAILURE; and corresponding CMakeLists.txt cmake_minimum_required(VERSION 3.25)
project(pybind11test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Warnings compiler flags
if(MSVC)
add_compile_options(/W4)
else()
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
include(FetchContent)
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11
GIT_TAG v2.10.4
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
SYSTEM
)
FetchContent_MakeAvailable(pybind11)
add_executable(pybind11test pybind11test.cpp)
target_link_libraries(pybind11test PRIVATE pybind11::embed) Am I missing something obvious to be able to catch pybind11 exceptions stemming from python? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The problem here is that your interpreter is scoped to the If you move the |
Beta Was this translation helpful? Give feedback.
The problem here is that your interpreter is scoped to the
try { ... }
and so isn't available anymore once you get to thecatch
, but thecatch
is trying to reach into python by thewhat()
call and so the interpreter still needs to be available to do anything with thepy::error_already_set
exception.If you move the
py::scoped_interpreter guard{};
above thetry
then the code should work as expected.