incorporated feedback

This commit is contained in:
Wenzel Jakob 2022-11-02 22:36:17 +01:00
parent cc03a56512
commit 780c6ff9c8
2 changed files with 30 additions and 31 deletions

View File

@ -401,6 +401,26 @@ inline void translate_local_exception(std::exception_ptr p) {
} }
#endif #endif
inline object get_internals_state_dict() {
object state_dict;
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
#else
# if PY_VERSION_HEX < 0x03090000
PyInterpreterState *istate = _PyInterpreterState_Get();
#else
PyInterpreterState *istate = PyInterpreterState_Get();
#endif
if (istate)
state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
#endif
if (!state_dict) {
raise_from(PyExc_SystemError, "get_internals(): could not acquire state dictionary!");
}
return state_dict;
}
/// Return a reference to the current `internals` data /// Return a reference to the current `internals` data
PYBIND11_NOINLINE internals &get_internals() { PYBIND11_NOINLINE internals &get_internals() {
internals **&internals_pp = get_internals_pp(); internals **&internals_pp = get_internals_pp();
@ -422,18 +442,7 @@ PYBIND11_NOINLINE internals &get_internals() {
constexpr const char *id_cstr = PYBIND11_INTERNALS_ID; constexpr const char *id_cstr = PYBIND11_INTERNALS_ID;
str id(id_cstr); str id(id_cstr);
dict state_dict; dict state_dict = get_internals_state_dict();
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
state_dict = reinterpret_borrow<dict>(PyEval_GetBuiltins());
#elif PY_VERSION_HEX < 0x03090000
state_dict = reinterpret_borrow<dict>(PyInterpreterState_GetDict(_PyInterpreterState_Get()));
#else
state_dict = reinterpret_borrow<dict>(PyInterpreterState_GetDict(PyInterpreterState_Get()));
#endif
if (!state_dict) {
pybind11_fail("get_internals(): could not acquire state dictionary!");
}
if (state_dict.contains(id_cstr)) { if (state_dict.contains(id_cstr)) {
object o = state_dict[id]; object o = state_dict[id];

View File

@ -168,18 +168,8 @@ TEST_CASE("There can be only one interpreter") {
py::initialize_interpreter(); py::initialize_interpreter();
} }
bool has_pybind11_internals_builtin() { bool has_pybind11_internals_state_dict() {
py::dict state_dict; return py::detail::get_internals_state_dict().contains(PYBIND11_INTERNALS_ID);
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
state_dict = py::reinterpret_borrow<py::dict>(PyEval_GetBuiltins());
#elif PY_VERSION_HEX < 0x03090000
state_dict
= py::reinterpret_borrow<py::dict>(PyInterpreterState_GetDict(_PyInterpreterState_Get()));
#else
state_dict
= py::reinterpret_borrow<py::dict>(PyInterpreterState_GetDict(PyInterpreterState_Get()));
#endif
return state_dict.contains(PYBIND11_INTERNALS_ID);
}; };
bool has_pybind11_internals_static() { bool has_pybind11_internals_static() {
@ -190,7 +180,7 @@ bool has_pybind11_internals_static() {
TEST_CASE("Restart the interpreter") { TEST_CASE("Restart the interpreter") {
// Verify pre-restart state. // Verify pre-restart state.
REQUIRE(py::module_::import("widget_module").attr("add")(1, 2).cast<int>() == 3); REQUIRE(py::module_::import("widget_module").attr("add")(1, 2).cast<int>() == 3);
REQUIRE(has_pybind11_internals_builtin()); REQUIRE(has_pybind11_internals_state_dict());
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
REQUIRE(py::module_::import("external_module").attr("A")(123).attr("value").cast<int>() REQUIRE(py::module_::import("external_module").attr("A")(123).attr("value").cast<int>()
== 123); == 123);
@ -207,10 +197,10 @@ TEST_CASE("Restart the interpreter") {
REQUIRE(Py_IsInitialized() == 1); REQUIRE(Py_IsInitialized() == 1);
// Internals are deleted after a restart. // Internals are deleted after a restart.
REQUIRE_FALSE(has_pybind11_internals_builtin()); REQUIRE_FALSE(has_pybind11_internals_state_dict());
REQUIRE_FALSE(has_pybind11_internals_static()); REQUIRE_FALSE(has_pybind11_internals_static());
pybind11::detail::get_internals(); pybind11::detail::get_internals();
REQUIRE(has_pybind11_internals_builtin()); REQUIRE(has_pybind11_internals_state_dict());
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp())
== py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>()); == py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>());
@ -225,13 +215,13 @@ TEST_CASE("Restart the interpreter") {
py::detail::get_internals(); py::detail::get_internals();
*static_cast<bool *>(ran) = true; *static_cast<bool *>(ran) = true;
}); });
REQUIRE_FALSE(has_pybind11_internals_builtin()); REQUIRE_FALSE(has_pybind11_internals_state_dict());
REQUIRE_FALSE(has_pybind11_internals_static()); REQUIRE_FALSE(has_pybind11_internals_static());
REQUIRE_FALSE(ran); REQUIRE_FALSE(ran);
py::finalize_interpreter(); py::finalize_interpreter();
REQUIRE(ran); REQUIRE(ran);
py::initialize_interpreter(); py::initialize_interpreter();
REQUIRE_FALSE(has_pybind11_internals_builtin()); REQUIRE_FALSE(has_pybind11_internals_state_dict());
REQUIRE_FALSE(has_pybind11_internals_static()); REQUIRE_FALSE(has_pybind11_internals_static());
// C++ modules can be reloaded. // C++ modules can be reloaded.
@ -253,7 +243,7 @@ TEST_CASE("Subinterpreter") {
REQUIRE(m.attr("add")(1, 2).cast<int>() == 3); REQUIRE(m.attr("add")(1, 2).cast<int>() == 3);
} }
REQUIRE(has_pybind11_internals_builtin()); REQUIRE(has_pybind11_internals_state_dict());
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
/// Create and switch to a subinterpreter. /// Create and switch to a subinterpreter.
@ -263,7 +253,7 @@ TEST_CASE("Subinterpreter") {
// Subinterpreters get their own copy of builtins. detail::get_internals() still // Subinterpreters get their own copy of builtins. detail::get_internals() still
// works by returning from the static variable, i.e. all interpreters share a single // works by returning from the static variable, i.e. all interpreters share a single
// global pybind11::internals; // global pybind11::internals;
REQUIRE_FALSE(has_pybind11_internals_builtin()); REQUIRE_FALSE(has_pybind11_internals_state_dict());
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
// Modules tags should be gone. // Modules tags should be gone.