@@ -84,15 +84,20 @@ TEST_CASE("There can be only one interpreter") {
84
84
py::initialize_interpreter ();
85
85
}
86
86
87
- bool has_pybind11_internals () {
87
+ bool has_pybind11_internals_builtin () {
88
88
auto builtins = py::handle (PyEval_GetBuiltins ());
89
89
return builtins.contains (PYBIND11_INTERNALS_ID);
90
90
};
91
91
92
+ bool has_pybind11_internals_static () {
93
+ return py::detail::get_internals_ptr () != nullptr ;
94
+ }
95
+
92
96
TEST_CASE (" Restart the interpreter" ) {
93
97
// Verify pre-restart state.
94
98
REQUIRE (py::module::import (" widget_module" ).attr (" add" )(1 , 2 ).cast <int >() == 3 );
95
- REQUIRE (has_pybind11_internals ());
99
+ REQUIRE (has_pybind11_internals_builtin ());
100
+ REQUIRE (has_pybind11_internals_static ());
96
101
97
102
// Restart the interpreter.
98
103
py::finalize_interpreter ();
@@ -102,9 +107,27 @@ TEST_CASE("Restart the interpreter") {
102
107
REQUIRE (Py_IsInitialized () == 1 );
103
108
104
109
// Internals are deleted after a restart.
105
- REQUIRE_FALSE (has_pybind11_internals ());
110
+ REQUIRE_FALSE (has_pybind11_internals_builtin ());
111
+ REQUIRE_FALSE (has_pybind11_internals_static ());
106
112
pybind11::detail::get_internals ();
107
- REQUIRE (has_pybind11_internals ());
113
+ REQUIRE (has_pybind11_internals_builtin ());
114
+ REQUIRE (has_pybind11_internals_static ());
115
+
116
+ // Make sure that an interpreter with no get_internals() created until finalize still gets the
117
+ // internals destroyed
118
+ py::finalize_interpreter ();
119
+ py::initialize_interpreter ();
120
+ bool ran = false ;
121
+ py::module::import (" __main__" ).attr (" internals_destroy_test" ) =
122
+ py::capsule (&ran, [](void *ran) { py::detail::get_internals (); *static_cast <bool *>(ran) = true ; });
123
+ REQUIRE_FALSE (has_pybind11_internals_builtin ());
124
+ REQUIRE_FALSE (has_pybind11_internals_static ());
125
+ REQUIRE_FALSE (ran);
126
+ py::finalize_interpreter ();
127
+ REQUIRE (ran);
128
+ py::initialize_interpreter ();
129
+ REQUIRE_FALSE (has_pybind11_internals_builtin ());
130
+ REQUIRE_FALSE (has_pybind11_internals_static ());
108
131
109
132
// C++ modules can be reloaded.
110
133
auto cpp_module = py::module::import (" widget_module" );
@@ -125,7 +148,8 @@ TEST_CASE("Subinterpreter") {
125
148
126
149
REQUIRE (m.attr (" add" )(1 , 2 ).cast <int >() == 3 );
127
150
}
128
- REQUIRE (has_pybind11_internals ());
151
+ REQUIRE (has_pybind11_internals_builtin ());
152
+ REQUIRE (has_pybind11_internals_static ());
129
153
130
154
// / Create and switch to a subinterpreter.
131
155
auto main_tstate = PyThreadState_Get ();
@@ -134,7 +158,8 @@ TEST_CASE("Subinterpreter") {
134
158
// Subinterpreters get their own copy of builtins. detail::get_internals() still
135
159
// works by returning from the static variable, i.e. all interpreters share a single
136
160
// global pybind11::internals;
137
- REQUIRE_FALSE (has_pybind11_internals ());
161
+ REQUIRE_FALSE (has_pybind11_internals_builtin ());
162
+ REQUIRE (has_pybind11_internals_static ());
138
163
139
164
// Modules tags should be gone.
140
165
REQUIRE_FALSE (py::hasattr (py::module::import (" __main__" ), " tag" ));
0 commit comments