diff --git a/python_bindings/nmslib.cc b/python_bindings/nmslib.cc index d203547..3a4279c 100644 --- a/python_bindings/nmslib.cc +++ b/python_bindings/nmslib.cc @@ -388,23 +388,32 @@ class PythonLogger int line, const char * function, const std::string & message) { - AcquireGIL l; - switch(severity) { - case LIB_DEBUG: - inner.attr("debug")(message); - break; - case LIB_INFO: - inner.attr("info")(message); - break; - case LIB_WARNING: - inner.attr("warning")(message); - break; - case LIB_ERROR: - inner.attr("error")(message); - break; - case LIB_FATAL: - inner.attr("critical")(message); - break; + // In cases when the interpreter was shutting down, attempting to log in python + // could throw an exception (https://github.com/nmslib/nmslib/issues/327). + // Logging shouldn't cause exceptions, so catch it and dump to stderr instead. + try { + AcquireGIL l; + switch(severity) { + case LIB_DEBUG: + inner.attr("debug")(message); + break; + case LIB_INFO: + inner.attr("info")(message); + break; + case LIB_WARNING: + inner.attr("warning")(message); + break; + case LIB_ERROR: + inner.attr("error")(message); + break; + case LIB_FATAL: + inner.attr("critical")(message); + break; + } + } catch (const std::exception & e) { + std::cerr << "Failed to log '" << message << "'. Exception:" << e.what() << std::endl; + } catch (...) { + std::cerr << "Failed to log '" << message << "'" << std::endl; } } }; diff --git a/python_bindings/tests/bindings_test.py b/python_bindings/tests/bindings_test.py index 7499275..56add76 100644 --- a/python_bindings/tests/bindings_test.py +++ b/python_bindings/tests/bindings_test.py @@ -169,5 +169,11 @@ def testSparse(self): self.assertEqual(index[3], [(3, 1.0)]) +class GlobalTestCase(unittest.TestCase): + def testGlobal(self): + # this is a one line reproduction of https://github.com/nmslib/nmslib/issues/327 + GlobalTestCase.index = nmslib.init() + + if __name__ == "__main__": unittest.main()