monarch-initiative / semsimian

Simple rust implementation of semantic similarity
BSD 3-Clause "New" or "Revised" License
9 stars 5 forks source link

Panic when user calls all x all only a predicate argument that doesn't exist in ontology #63

Open justaddcoffee opened 1 year ago

justaddcoffee commented 1 year ago

This panic happens when a user specifies only a predicate that doesn't exist in ontology (I'm using the try_rwlock_instead_of_mutex branch, since it looks like this will be merged soon-ish). This is what happens on the Oak side:

(rustsim) ~/PythonProject/ontology-access-kit implement_all_by_all_in_semsimian $ time runoak --stacktrace -i semsimian:sqlite:obo:bfo similarity -p doesntexist .all @ .all > /dev/null 
[00:00:00] Building closure and IC map: ████████████████████████████████████████ 100%thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', src/lib.rs:56:54
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
  File "/Users/jtr4v/anaconda3/envs/rustsim/bin/runoak", line 6, in <module>
    sys.exit(main())
  File "/Users/jtr4v/anaconda3/envs/rustsim/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/jtr4v/anaconda3/envs/rustsim/lib/python3.9/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/Users/jtr4v/anaconda3/envs/rustsim/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/jtr4v/anaconda3/envs/rustsim/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/jtr4v/anaconda3/envs/rustsim/lib/python3.9/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/Users/jtr4v/PythonProject/ontology-access-kit/src/oaklib/cli.py", line 2746, in similarity
    for sim in impl.all_by_all_pairwise_similarity(
  File "/Users/jtr4v/PythonProject/ontology-access-kit/src/oaklib/implementations/semsimian/semsimian_implementation.py", line 134, in all_by_all_pairwise_similarity
    all_results = self.semsimian.all_by_all_pairwise_similarity(
pyo3_runtime.PanicException: called `Option::unwrap()` on a `None` value

real    0m2.420s
user    0m2.347s
sys     0m2.272s
(rustsim) ~/PythonProject/ontology-access-kit implement_all_by_all_in_semsimian $ 

Not a problem if they specify one that exists and one that does not:

(rustsim) ~/PythonProject/ontology-access-kit implement_all_by_all_in_semsimian $ time runoak --stacktrace -i semsimian:sqlite:obo:bfo similarity -p i,doesntexist .all @ .all > /dev/null 
[00:00:00] Building closure and IC map: ████████████████████████████████████████ 100%
real    0m3.181s
user    0m3.165s
sys     0m2.568s
(rustsim) ~/PythonProject/ontology-access-kit implement_all_by_all_in_semsimian $ 

I think we probably just need to check for this in update_closure_and_ic_map here and also need a test on the semsimian side, something like:

let pw = semsimian.all_by_all_pairwise_similarity(subjects, objects, a_single_predicate_that_doesnt_exist)
// assert there is no panic
justaddcoffee commented 1 year ago

Stack trace from rust side:

/Users/jtr4v/anaconda3/envs/rustsim/bin/python /Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pycharm/_jb_pytest_runner.py --target test_python.py::testSemsimianWithPython.test_all_by_all_pairwise_similarity_non_existent_predicate 
Testing started at 6:41 PM ...
Launching pytest with arguments test_python.py::testSemsimianWithPython::test_all_by_all_pairwise_similarity_non_existent_predicate --no-header --no-summary -q in /Users/jtr4v/PythonProject/semsimian/python/tests

============================= test session starts ==============================
collecting ... collected 1 item

test_python.py::testSemsimianWithPython::test_all_by_all_pairwise_similarity_non_existent_predicate FAILED [100%]Returning key: +non_existent_predicate
Returning key: +non_existent_predicate
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', src/lib.rs:56:54
stack backtrace:
   0: begin_panic_handler
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/std/src/panicking.rs:593:5
   1: panic_fmt
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/core/src/panicking.rs:67:14
   2: panic
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/core/src/panicking.rs:117:5
   3: core::option::Option<T>::unwrap
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/core/src/option.rs:935:21
   4: semsimian::RustSemsimian::update_closure_and_ic_map
             at /Users/jtr4v/PythonProject/semsimian/src/lib.rs:56:13
   5: semsimian::Semsimian::all_by_all_pairwise_similarity
             at /Users/jtr4v/PythonProject/semsimian/src/lib.rs:178:9
   6: semsimian::_::<impl semsimian::Semsimian>::__pymethod_all_by_all_pairwise_similarity__
             at /Users/jtr4v/PythonProject/semsimian/src/lib.rs:143:1
   7: pyo3::impl_::trampoline::fastcall_with_keywords::{{closure}}
             at /Users/jtr4v/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pyo3-0.18.3/src/impl_/trampoline.rs:41:35
   8: pyo3::impl_::trampoline::trampoline_inner::{{closure}}
             at /Users/jtr4v/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pyo3-0.18.3/src/impl_/trampoline.rs:204:54
   9: std::panicking::try::do_call
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/std/src/panicking.rs:500:40
  10: ___rust_try
  11: std::panicking::try
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/std/src/panicking.rs:464:19
  12: std::panic::catch_unwind
             at /rustc/e6d4725c76f3b526c74454bc51afdf6daf133506/library/std/src/panic.rs:142:14
  13: pyo3::impl_::trampoline::trampoline_inner
             at /Users/jtr4v/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pyo3-0.18.3/src/impl_/trampoline.rs:204:9
  14: pyo3::impl_::trampoline::fastcall_with_keywords
             at /Users/jtr4v/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pyo3-0.18.3/src/impl_/trampoline.rs:41:13
  15: semsimian::_::<impl pyo3::impl_::pyclass::PyMethods<semsimian::Semsimian> for pyo3::impl_::pyclass::PyClassImplCollector<semsimian::Semsimian>>::py_methods::ITEMS::trampoline
             at /Users/jtr4v/PythonProject/semsimian/src/lib.rs:143:1
  16: _method_vectorcall_FASTCALL_KEYWORDS
  17: __PyEval_EvalFrameDefault
  18: __PyFunction_Vectorcall
  19: _method_vectorcall
  20: __PyEval_EvalFrameDefault
  21: __PyFunction_Vectorcall
  22: __PyEval_EvalFrameDefault
  23: __PyFunction_Vectorcall
  24: _method_vectorcall
  25: __PyEval_EvalFrameDefault
  26: __PyFunction_Vectorcall
  27: __PyObject_Call_Prepend
  28: _slot_tp_call
  29: __PyEval_EvalFrameDefault
  30: __PyFunction_Vectorcall
  31: __PyEval_EvalFrameDefault
  32: __PyFunction_Vectorcall
  33: __PyEval_EvalFrameDefault
  34: __PyFunction_Vectorcall
  35: __PyEval_EvalFrameDefault
  36: __PyFunction_Vectorcall
  37: _method_vectorcall
  38: __PyEval_EvalFrameDefault
  39: __PyFunction_Vectorcall
  40: __PyObject_Call_Prepend
  41: _slot_tp_call
  42: __PyEval_EvalFrameDefault
  43: __PyFunction_Vectorcall
  44: __PyEval_EvalFrameDefault
  45: __PyFunction_Vectorcall
  46: _method_vectorcall
  47: __PyEval_EvalFrameDefault
  48: __PyFunction_Vectorcall
  49: __PyEval_EvalFrameDefault
  50: __PyFunction_Vectorcall
  51: __PyEval_EvalFrameDefault
  52: __PyFunction_Vectorcall
  53: __PyEval_EvalFrameDefault
  54: __PyFunction_Vectorcall
  55: __PyEval_EvalFrameDefault
  56: __PyFunction_Vectorcall
  57: __PyEval_EvalFrameDefault
  58: __PyFunction_Vectorcall
  59: _method_vectorcall
  60: __PyEval_EvalFrameDefault
  61: __PyFunction_Vectorcall
  62: __PyObject_Call_Prepend
  63: _slot_tp_call
  64: __PyEval_EvalFrameDefault
  65: __PyFunction_Vectorcall
  66: __PyEval_EvalFrameDefault
  67: __PyFunction_Vectorcall
  68: __PyEval_EvalFrameDefault
  69: __PyFunction_Vectorcall
  70: _method_vectorcall
  71: __PyEval_EvalFrameDefault
  72: __PyFunction_Vectorcall
  73: __PyObject_Call_Prepend
  74: _slot_tp_call
  75: __PyEval_EvalFrameDefault
  76: __PyFunction_Vectorcall
  77: __PyEval_EvalFrameDefault
  78: __PyFunction_Vectorcall
  79: __PyEval_EvalFrameDefault
  80: __PyFunction_Vectorcall
  81: __PyEval_EvalFrameDefault
  82: __PyFunction_Vectorcall
  83: __PyEval_EvalFrameDefault
  84: __PyFunction_Vectorcall
  85: _method_vectorcall
  86: __PyEval_EvalFrameDefault
  87: __PyFunction_Vectorcall
  88: __PyObject_Call_Prepend
  89: _slot_tp_call
  90: __PyEval_EvalFrameDefault
  91: __PyFunction_Vectorcall
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

test_python.py:33 (testSemsimianWithPython.test_all_by_all_pairwise_similarity_non_existent_predicate)
self = <test_python.testSemsimianWithPython testMethod=test_all_by_all_pairwise_similarity_non_existent_predicate>

    def test_all_by_all_pairwise_similarity_non_existent_predicate(self):
        subject_terms = {"apple", "banana", "orange"}
        object_terms = {"orange", "pear", "kiwi"}
        predicates = {"non_existent_predicate"}
        orange_mica = {"orange", "pear"}
>       result = self.semsimian.all_by_all_pairwise_similarity(
            subject_terms, object_terms, predicates
        )
E       pyo3_runtime.PanicException: called `Option::unwrap()` on a `None` value

test_python.py:39: PanicException