incorporated feedback
diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h
index 6049791..93cf246 100644
--- a/include/pybind11/detail/internals.h
+++ b/include/pybind11/detail/internals.h
@@ -401,6 +401,26 @@
 }
 #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
 PYBIND11_NOINLINE internals &get_internals() {
     internals **&internals_pp = get_internals_pp();
@@ -422,18 +442,7 @@
     constexpr const char *id_cstr = PYBIND11_INTERNALS_ID;
     str id(id_cstr);
 
-    dict 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!");
-    }
+    dict state_dict = get_internals_state_dict();
 
     if (state_dict.contains(id_cstr)) {
         object o = state_dict[id];
diff --git a/tests/test_embed/test_interpreter.cpp b/tests/test_embed/test_interpreter.cpp
index afcb4fc..a363bcb 100644
--- a/tests/test_embed/test_interpreter.cpp
+++ b/tests/test_embed/test_interpreter.cpp
@@ -168,18 +168,8 @@
     py::initialize_interpreter();
 }
 
-bool has_pybind11_internals_builtin() {
-    py::dict state_dict;
-#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_state_dict() {
+    return py::detail::get_internals_state_dict().contains(PYBIND11_INTERNALS_ID);
 };
 
 bool has_pybind11_internals_static() {
@@ -190,7 +180,7 @@
 TEST_CASE("Restart the interpreter") {
     // Verify pre-restart state.
     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(py::module_::import("external_module").attr("A")(123).attr("value").cast<int>()
             == 123);
@@ -207,10 +197,10 @@
     REQUIRE(Py_IsInitialized() == 1);
 
     // 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());
     pybind11::detail::get_internals();
-    REQUIRE(has_pybind11_internals_builtin());
+    REQUIRE(has_pybind11_internals_state_dict());
     REQUIRE(has_pybind11_internals_static());
     REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp())
             == py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>());
@@ -225,13 +215,13 @@
               py::detail::get_internals();
               *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(ran);
     py::finalize_interpreter();
     REQUIRE(ran);
     py::initialize_interpreter();
-    REQUIRE_FALSE(has_pybind11_internals_builtin());
+    REQUIRE_FALSE(has_pybind11_internals_state_dict());
     REQUIRE_FALSE(has_pybind11_internals_static());
 
     // C++ modules can be reloaded.
@@ -253,7 +243,7 @@
 
         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());
 
     /// Create and switch to a subinterpreter.
@@ -263,7 +253,7 @@
     // 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
     // global pybind11::internals;
-    REQUIRE_FALSE(has_pybind11_internals_builtin());
+    REQUIRE_FALSE(has_pybind11_internals_state_dict());
     REQUIRE(has_pybind11_internals_static());
 
     // Modules tags should be gone.