Skip to content

Commit

Permalink
implemented py::CustomExcHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
bab2min committed Feb 14, 2024
1 parent 18844ea commit ec38238
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 59 deletions.
20 changes: 10 additions & 10 deletions src/KiwiPy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::pair<uint32_t, std::u16string>> KiwiObject::addRule(const char* tag, PyObject* replacer, float score)
Expand Down Expand Up @@ -1930,5 +1924,11 @@ py::UniqueObj KiwiObject::makeHSDataset(PyObject* inputPathes, size_t batchSize,
PyMODINIT_FUNC PyInit__kiwipiepy()
{
import_array();
py::CustomExcHandler::add<kiwi::IOException, py::OSError>();
py::CustomExcHandler::add<kiwi::FormatException, py::ValueError>();
py::CustomExcHandler::add<kiwi::UnicodeException, py::ValueError>();
py::CustomExcHandler::add<kiwi::UnknownMorphemeException, py::ValueError>();
py::CustomExcHandler::add<kiwi::SwTokenizerException, py::ValueError>();
py::CustomExcHandler::add<kiwi::Exception, py::Exception>();
return gModule.init();
}
117 changes: 68 additions & 49 deletions src/PyUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <optional>
#include <variant>
#include <numeric>
#include <typeinfo>
#include <typeindex>

#ifdef _DEBUG
#undef _DEBUG
Expand Down Expand Up @@ -993,8 +995,8 @@ namespace py
}
else
{
return false;
}
return false;
}
};

Expand Down Expand Up @@ -1829,18 +1831,28 @@ namespace py
return true;
}

template<typename _Fn>
PY_STRONG_INLINE auto handleExc(_Fn&& fn)
-> typename std::enable_if<std::is_pointer<decltype(fn())>::value, decltype(fn())>::type
class CustomExcHandler
{
try
static std::unordered_map<std::type_index, PyObject*> handlers;

public:
template<class CustomExc, class PyExc>
static void add()
{
return fn();
handlers[std::type_index(typeid(CustomExc))] = PyExc{ "" }.pytype();
}
catch (const ExcPropagation&)

static const std::unordered_map<std::type_index, PyObject*>& get()
{
return handlers;
}
catch (const BaseException& e)
};

std::unordered_map<std::type_index, PyObject*> CustomExcHandler::handlers;

namespace detail
{
inline void setPyError(PyObject* errType, const char* errMsg)
{
if (PyErr_Occurred())
{
Expand All @@ -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<typename _Fn>
PY_STRONG_INLINE auto handleExc(_Fn&& fn)
-> typename std::enable_if<std::is_pointer<decltype(fn())>::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)
{
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand Down

0 comments on commit ec38238

Please sign in to comment.