From b52cd9bd6b95a69813cd2651e9869e99c36c8de8 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Mon, 7 Oct 2019 21:24:28 +0100 Subject: [PATCH] Update pybind11 to v2.4.2 v2.3.0 fixed GIL handling bugs, which means we need to explicitly stop storing the Python logging callback before exiting, or the exit will hang. --- CMakeLists.txt | 2 +- src/main.cpp | 7 +++++++ test/test.py | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e2af2d..585abee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ configure_file("${CMAKE_SOURCE_DIR}/python/setup.py" "${CMAKE_BINARY_DIR}/genera # pybind11 ####################################### -set(PYBIND11_VERSION "2.2.4") +set(PYBIND11_VERSION "2.4.2") set(PYBIND11_URL "https://github.com/pybind/pybind11/archive/v${PYBIND11_VERSION}.tar.gz") set(PYBIND11_DOWNLOAD_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-${PYBIND11_VERSION}.tar.gz") set(PYBIND11_EXTRACTED_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-${PYBIND11_VERSION}") diff --git a/src/main.cpp b/src/main.cpp index 1f24af4..faed9c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -159,6 +159,13 @@ void bindClasses(pybind11::module& module) { void bindFunctions(pybind11::module& module) { module.def("set_logging_callback", &SetLoggingCallback); + // Need to clear the stored logging callback when exiting, or Python will + // hang because the callback pointer is still stored by libloot. + auto atexit = pybind11::module::import("atexit"); + atexit.attr("register")(pybind11::cpp_function([]() { + SetLoggingCallback(nullptr); + })); + module.def("is_compatible", &IsCompatible); module.def("initialise_locale", &InitialiseLocale, arg("id") = ""); diff --git a/test/test.py b/test/test.py index e4a39e3..5bc14f6 100644 --- a/test/test.py +++ b/test/test.py @@ -34,10 +34,12 @@ class GameFixture(unittest.TestCase): data_path = os.path.join(self.game_path, 'Data') master_file = os.path.join(data_path, 'Oblivion.esm') - os.makedirs(data_path) + if not os.path.exists(data_path): + os.makedirs(data_path) open(master_file, 'a').close() - os.makedirs(self.local_path) + if not os.path.exists(self.local_path): + os.makedirs(self.local_path) def tearDown(self): shutil.rmtree(self.game_path)