From ec382389cd2f3aab2c95ac9a134953edbb64bdd9 Mon Sep 17 00:00:00 2001 From: bab2min Date: Thu, 15 Feb 2024 02:19:05 +0900 Subject: [PATCH] implemented `py::CustomExcHandler` --- src/KiwiPy.cpp | 20 ++++----- src/PyUtils.h | 117 ++++++++++++++++++++++++++++--------------------- 2 files changed, 78 insertions(+), 59 deletions(-) diff --git a/src/KiwiPy.cpp b/src/KiwiPy.cpp index 96e8515..66ec200 100644 --- a/src/KiwiPy.cpp +++ b/src/KiwiPy.cpp @@ -1639,16 +1639,10 @@ bool KiwiObject::addPreAnalyzedWord(const char* form, PyObject* oAnalyzed, float { throw py::ValueError{ "All items of `analyzed` must be in the type `Tuple[str, str]` or `Tuple[str, str, int, int]`."}; } - try - { - auto added = builder.addPreAnalyzedWord(utf8To16(form), analyzed, positions, score); - if (added) kiwi = Kiwi{}; - return added; - } - catch (const UnknownMorphemeException& e) - { - throw py::ValueError{ e.what() }; - } + + auto added = builder.addPreAnalyzedWord(utf8To16(form), analyzed, positions, score); + if (added) kiwi = Kiwi{}; + return added; } std::vector> KiwiObject::addRule(const char* tag, PyObject* replacer, float score) @@ -1930,5 +1924,11 @@ py::UniqueObj KiwiObject::makeHSDataset(PyObject* inputPathes, size_t batchSize, PyMODINIT_FUNC PyInit__kiwipiepy() { import_array(); + py::CustomExcHandler::add(); + py::CustomExcHandler::add(); + py::CustomExcHandler::add(); + py::CustomExcHandler::add(); + py::CustomExcHandler::add(); + py::CustomExcHandler::add(); return gModule.init(); } diff --git a/src/PyUtils.h b/src/PyUtils.h index ec86749..46a5992 100644 --- a/src/PyUtils.h +++ b/src/PyUtils.h @@ -16,6 +16,8 @@ #include #include #include +#include +#include #ifdef _DEBUG #undef _DEBUG @@ -993,8 +995,8 @@ namespace py } else { - return false; } + return false; } }; @@ -1829,18 +1831,28 @@ namespace py return true; } - template - PY_STRONG_INLINE auto handleExc(_Fn&& fn) - -> typename std::enable_if::value, decltype(fn())>::type + class CustomExcHandler { - try + static std::unordered_map handlers; + + public: + template + static void add() { - return fn(); + handlers[std::type_index(typeid(CustomExc))] = PyExc{ "" }.pytype(); } - catch (const ExcPropagation&) + + static const std::unordered_map& get() { + return handlers; } - catch (const BaseException& e) + }; + + std::unordered_map CustomExcHandler::handlers; + + namespace detail + { + inline void setPyError(PyObject* errType, const char* errMsg) { if (PyErr_Occurred()) { @@ -1853,16 +1865,43 @@ namespace py Py_DECREF(tb); } Py_DECREF(exc); - PyObject* et = e.pytype(); - val2 = PyObject_CallFunctionObjArgs(et, py::UniqueObj{ buildPyValue(e.what()) }.get(), nullptr); + PyObject* et = errType; + val2 = PyObject_CallFunctionObjArgs(et, py::UniqueObj{ buildPyValue(errMsg) }.get(), nullptr); PyException_SetCause(val2, val); PyErr_SetObject(et, val2); Py_DECREF(val2); } else { - PyErr_SetString(e.pytype(), e.what()); + PyErr_SetString(errType, errMsg); + } + } + } + + template + PY_STRONG_INLINE auto handleExc(_Fn&& fn) + -> typename std::enable_if::value, decltype(fn())>::type + { + try + { + return fn(); + } + catch (const ExcPropagation&) + { + } + catch (const BaseException& e) + { + detail::setPyError(e.pytype(), e.what()); + } + catch (const std::exception& e) + { + auto customHandlers = CustomExcHandler{}.get(); + auto it = customHandlers.find(std::type_index(typeid(e))); + if (it == customHandlers.end()) + { + throw; } + detail::setPyError(it->second, e.what()); } /*catch (const std::exception& e) { @@ -1885,27 +1924,17 @@ namespace py } catch (const BaseException& e) { - if (PyErr_Occurred()) - { - PyObject* exc, * val, * tb, * val2; - PyErr_Fetch(&exc, &val, &tb); - PyErr_NormalizeException(&exc, &val, &tb); - if (tb) - { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - Py_DECREF(exc); - PyObject* et = e.pytype(); - val2 = PyObject_CallFunctionObjArgs(et, py::UniqueObj{ buildPyValue(e.what()) }.get(), nullptr); - PyException_SetCause(val2, val); - PyErr_SetObject(et, val2); - Py_DECREF(val2); - } - else + detail::setPyError(e.pytype(), e.what()); + } + catch (const std::exception& e) + { + auto customHandlers = CustomExcHandler{}.get(); + auto it = customHandlers.find(std::type_index(typeid(e))); + if (it == customHandlers.end()) { - PyErr_SetString(e.pytype(), e.what()); + throw; } + detail::setPyError(it->second, e.what()); } /*catch (const std::exception& e) { @@ -1928,27 +1957,17 @@ namespace py } catch (const BaseException& e) { - if (PyErr_Occurred()) - { - PyObject* exc, * val, * tb, * val2; - PyErr_Fetch(&exc, &val, &tb); - PyErr_NormalizeException(&exc, &val, &tb); - if (tb) - { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - Py_DECREF(exc); - PyObject* et = e.pytype(); - val2 = PyObject_CallFunctionObjArgs(et, py::UniqueObj{ buildPyValue(e.what()) }.get(), nullptr); - PyException_SetCause(val2, val); - PyErr_SetObject(et, val2); - Py_DECREF(val2); - } - else + detail::setPyError(e.pytype(), e.what()); + } + catch (const std::exception& e) + { + auto customHandlers = CustomExcHandler{}.get(); + auto it = customHandlers.find(std::type_index(typeid(e))); + if (it == customHandlers.end()) { - PyErr_SetString(e.pytype(), e.what()); + throw; } + detail::setPyError(it->second, e.what()); } /*catch (const std::exception& e) {