Skip to content

Commit

Permalink
Add test_class_release_gil_before_calling_cpp_dtor
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralf W. Grosse-Kunstleve committed Jan 16, 2024
1 parent d7a9411 commit 686ec79
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ set(PYBIND11_TEST_FILES
test_callbacks
test_chrono
test_class
test_class_release_gil_before_calling_cpp_dtor
test_class_sh_basic
test_class_sh_disowning
test_class_sh_disowning_mi
Expand Down
51 changes: 51 additions & 0 deletions tests/test_class_release_gil_before_calling_cpp_dtor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <pybind11/pybind11.h>

#include "pybind11_tests.h"

#include <string>
#include <unordered_map>

namespace pybind11_tests {
namespace class_release_gil_before_calling_cpp_dtor {

using RegistryType = std::unordered_map<std::string, int>;

RegistryType &PyGILState_Check_Results() {
static auto *singleton = new RegistryType();
return *singleton;
}

template <int> // Using int as a trick to easily generate a series of types.
struct ProbeType {
private:
std::string unique_key;

public:
explicit ProbeType(const std::string &unique_key) : unique_key{unique_key} {}

~ProbeType() {
RegistryType &reg = PyGILState_Check_Results();
assert(reg.count(unique_key) == 0);
reg[unique_key] = PyGILState_Check();
}
};

} // namespace class_release_gil_before_calling_cpp_dtor
} // namespace pybind11_tests

TEST_SUBMODULE(class_release_gil_before_calling_cpp_dtor, m) {
using namespace pybind11_tests::class_release_gil_before_calling_cpp_dtor;

py::class_<ProbeType<0>>(m, "ProbeType0").def(py::init<std::string>());

py::class_<ProbeType<1>>(m, "ProbeType1", py::release_gil_before_calling_cpp_dtor())
.def(py::init<std::string>());

m.def("GetPyGILState_Check_Result", [](const std::string &unique_key) -> std::string {
RegistryType &reg = PyGILState_Check_Results();
if (reg.count(unique_key) == 0) {
return "MISSING";
}
return std::to_string(reg[unique_key]);
});
}
19 changes: 19 additions & 0 deletions tests/test_class_release_gil_before_calling_cpp_dtor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import gc

import pytest

from pybind11_tests import class_release_gil_before_calling_cpp_dtor as m


@pytest.mark.parametrize(
("probe_type", "unique_key", "expected_result"),
[
(m.ProbeType0, "without_manipulating_gil", "1"),
(m.ProbeType1, "release_gil_before_calling_cpp_dtor", "0"),
],
)
def test_gil_state_check_results(probe_type, unique_key, expected_result):
probe_type(unique_key)
gc.collect()
result = m.GetPyGILState_Check_Result(unique_key)
assert result == expected_result

0 comments on commit 686ec79

Please sign in to comment.