diff --git a/.travis.yml b/.travis.yml index 06ca91d..64457d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,13 @@ matrix: - os: linux env: PYTHON=3 - os: osx - env: PYTHON=3.6 + env: PYTHON=3 + osx_image: xcode9.3 + python: 3.7.0 + - os: osx + env: PYTHON=2 + osx_image: xcode9.3 + python: 2.7.14 allow_failures: - os: osx @@ -29,17 +35,27 @@ addons: before_install: - | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then export CXX=g++-4.8 CC=gcc-4.8; fi - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "${PYTHON:0:1}" = "3" ]; then - brew update - brew upgrade python - command curl -sSL https://rvm.io/mpapis.asc | gpg --import -; - rvm get stable - else + PIP=pip + PY=python + if [ "$TRAVIS_OS_NAME" = "linux" ]; then + export CXX=g++-4.8 CC=gcc-4.8; pip install --user --upgrade pip virtualenv virtualenv -p python$PYTHON venv source venv/bin/activate - fi + fi + + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + brew update + brew install gcc + PIP=pip2 + PY=python2 + if [ "${PYTHON:0:1}" = "3" ]; then + brew upgrade python + brew install python3 + PIP=pip3 + PY=python3 + fi + fi install: - | @@ -49,22 +65,20 @@ install: cmake similarity_search fi make -j 4 - travis_wait travis_retry pip install -r python_bindings/requirements.txt scipy six flake8 - travis_retry cd python_bindings && python setup.py build install && cd .. + travis_wait travis_retry $PIP install -r python_bindings/requirements.txt scipy six flake8 + travis_retry cd python_bindings && $PY setup.py build install && cd .. script: +- $PY --version +- cd python_bindings && $PY setup.py test && flake8 && cd .. - | set -e - if [ "$TRAVIS_OS_NAME" = "linux" -o "$TRAVIS_OS_NAME" = "osx" ] ; then + if [ "$TRAVIS_OS_NAME" = "linux" ] ; then cd similarity_search; ./release/bunit ./release/test_integr integr.log cd .. fi - cd python_bindings - python setup.py test - flake8 - cd .. cache: - apt 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()