diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index e05380947c..6854d89ed6 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1342,13 +1342,18 @@ class module_ : public object { // GraalPy doesn't support PyModule_GetFilenameObject, // so getting by attribute (see PR #5584) handle this_module = m_ptr; - result.attr("__file__") = this_module.attr("__file__"); + if (object this_file = getattr(this_module, "__file__", none())) { + result.attr("__file__") = this_file; + } #else handle this_file = PyModule_GetFilenameObject(m_ptr); - if (!this_file) { + if (this_file) { + result.attr("__file__") = this_file; + } else if (PyErr_ExceptionMatches(PyExc_SystemError) != 0) { + PyErr_Clear(); + } else { throw error_already_set(); } - result.attr("__file__") = this_file; #endif attr(name) = result; return result; diff --git a/tests/test_embed/test_interpreter.cpp b/tests/test_embed/test_interpreter.cpp index c6c8a22d98..56496212fd 100644 --- a/tests/test_embed/test_interpreter.cpp +++ b/tests/test_embed/test_interpreter.cpp @@ -61,6 +61,9 @@ PYBIND11_EMBEDDED_MODULE(widget_module, m) { .def_property_readonly("the_message", &Widget::the_message); m.def("add", [](int i, int j) { return i + j; }); + + auto sub = m.def_submodule("sub"); + sub.def("add", [](int i, int j) { return i + j; }); } PYBIND11_EMBEDDED_MODULE(trampoline_module, m) { @@ -316,6 +319,9 @@ TEST_CASE("Restart the interpreter") { auto cpp_module = py::module_::import("widget_module"); REQUIRE(cpp_module.attr("add")(1, 2).cast() == 3); + // Also verify submodules work + REQUIRE(cpp_module.attr("sub").attr("add")(1, 41).cast() == 42); + // C++ type information is reloaded and can be used in python modules. auto py_module = py::module_::import("test_interpreter"); auto py_widget = py_module.attr("DerivedWidget")("Hello after restart");