From 8b0cda79ca2dec8e41ec1b8c5d15735436b73363 Mon Sep 17 00:00:00 2001 From: StarQTius Date: Thu, 17 Feb 2022 01:35:56 +0100 Subject: [PATCH 1/3] Clear local internals after finalizing interpreter --- include/pybind11/embed.h | 3 +++ tests/test_embed/test_interpreter.cpp | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/pybind11/embed.h b/include/pybind11/embed.h index 8e998fc3c6..439258444c 100644 --- a/include/pybind11/embed.h +++ b/include/pybind11/embed.h @@ -199,6 +199,9 @@ inline void finalize_interpreter() { internals_ptr_ptr = capsule(builtins[id]); } + detail::get_local_internals().registered_types_cpp.clear(); + detail::get_local_internals().registered_exception_translators.clear(); + Py_Finalize(); if (internals_ptr_ptr) { diff --git a/tests/test_embed/test_interpreter.cpp b/tests/test_embed/test_interpreter.cpp index f2f2c29609..d9dad1c94c 100644 --- a/tests/test_embed/test_interpreter.cpp +++ b/tests/test_embed/test_interpreter.cpp @@ -375,3 +375,20 @@ TEST_CASE("sys.argv gets initialized properly") { } py::initialize_interpreter(); } + +TEST_CASE("make_iterator can be called before then after finalizing an interpreter") { + py::finalize_interpreter(); + + std::vector container; + { + pybind11::scoped_interpreter g; + auto iter = pybind11::make_iterator(container.begin(), container.end()); + } + + REQUIRE_NOTHROW([&]() { + pybind11::scoped_interpreter g; + auto iter = pybind11::make_iterator(container.begin(), container.end()); + }()); + + py::initialize_interpreter(); +} From 3400965b389d6ad5a44712e3995e127bec7b3896 Mon Sep 17 00:00:00 2001 From: StarQTius Date: Sat, 19 Feb 2022 23:56:46 +0100 Subject: [PATCH 2/3] Add descriptive comments --- include/pybind11/embed.h | 2 +- tests/test_embed/test_interpreter.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/pybind11/embed.h b/include/pybind11/embed.h index 439258444c..dc2ae3cedd 100644 --- a/include/pybind11/embed.h +++ b/include/pybind11/embed.h @@ -198,7 +198,7 @@ inline void finalize_interpreter() { if (builtins.contains(id) && isinstance(builtins[id])) { internals_ptr_ptr = capsule(builtins[id]); } - + // Local internals contains data managed by the current interpreter, so we must clear them to avoid undefined behaviors when initializing another interpreter detail::get_local_internals().registered_types_cpp.clear(); detail::get_local_internals().registered_exception_translators.clear(); diff --git a/tests/test_embed/test_interpreter.cpp b/tests/test_embed/test_interpreter.cpp index d9dad1c94c..1c45457a05 100644 --- a/tests/test_embed/test_interpreter.cpp +++ b/tests/test_embed/test_interpreter.cpp @@ -377,6 +377,7 @@ TEST_CASE("sys.argv gets initialized properly") { } TEST_CASE("make_iterator can be called before then after finalizing an interpreter") { + // Reproduction of issue #2101 (https://github.com/pybind/pybind11/issues/2101) py::finalize_interpreter(); std::vector container; From ec8fe63dc235a871ea5459c9a4d9d9394e1d75f8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 19 Feb 2022 22:57:27 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- include/pybind11/embed.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/pybind11/embed.h b/include/pybind11/embed.h index dc2ae3cedd..98cc3e4664 100644 --- a/include/pybind11/embed.h +++ b/include/pybind11/embed.h @@ -198,7 +198,8 @@ inline void finalize_interpreter() { if (builtins.contains(id) && isinstance(builtins[id])) { internals_ptr_ptr = capsule(builtins[id]); } - // Local internals contains data managed by the current interpreter, so we must clear them to avoid undefined behaviors when initializing another interpreter + // Local internals contains data managed by the current interpreter, so we must clear them to + // avoid undefined behaviors when initializing another interpreter detail::get_local_internals().registered_types_cpp.clear(); detail::get_local_internals().registered_exception_translators.clear();