forked from rapidsai/cudf
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inline Cython exception handler (rapidsai#13411)
I originally placed the exception handler into a separate C++ header file that could be included by the Cython header because I figured that reading C++ inlined in Cython would be more confusing to devs. Unfortunately, the current approach complicates the build system due to the need to ensure that the directory containing the C++ header is always in the include path, which becomes problematic depending on where the files including the exception handler are (anywhere outside of `_lib` becomes problematic). Inlining is the simplest solution to this problem. Authors: - Vyas Ramasubramani (https://github.com/vyasr) Approvers: - Ashwin Srinath (https://github.com/shwina) - Bradley Dice (https://github.com/bdice) URL: rapidsai#13411
- Loading branch information
Showing
6 changed files
with
69 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,69 @@ | ||
# Copyright (c) 2023, NVIDIA CORPORATION. | ||
|
||
|
||
cdef extern from "exception_handler.hpp" namespace "cudf_python::exceptions": | ||
# See | ||
# https://github.com/cython/cython/blob/master/Cython/Utility/CppSupport.cpp | ||
# for the original Cython exception handler. | ||
cdef extern from *: | ||
""" | ||
#include <Python.h> | ||
#include <cudf/utilities/error.hpp> | ||
#include <ios> | ||
#include <stdexcept> | ||
namespace { | ||
/** | ||
* @brief Exception handler to map C++ exceptions to Python ones in Cython | ||
* | ||
* This exception handler extends the base exception handler provided by | ||
* Cython. In addition to the exceptions that Cython itself supports, this | ||
* file adds support for additional exceptions thrown by libcudf that need | ||
* to be mapped to specific Python exceptions. | ||
* | ||
* Since this function interoperates with Python's exception state, it | ||
* does not throw any C++ exceptions. | ||
*/ | ||
void cudf_exception_handler() | ||
{ | ||
// Catch a handful of different errors here and turn them into the | ||
// equivalent Python errors. | ||
try { | ||
if (PyErr_Occurred()) | ||
; // let latest Python exn pass through and ignore the current one | ||
throw; | ||
} catch (const std::bad_alloc& exn) { | ||
PyErr_SetString(PyExc_MemoryError, exn.what()); | ||
} catch (const std::bad_cast& exn) { | ||
PyErr_SetString(PyExc_TypeError, exn.what()); | ||
} catch (const std::domain_error& exn) { | ||
PyErr_SetString(PyExc_ValueError, exn.what()); | ||
} catch (const cudf::data_type_error& exn) { | ||
// Catch subclass (data_type_error) before parent (invalid_argument) | ||
PyErr_SetString(PyExc_TypeError, exn.what()); | ||
} catch (const std::invalid_argument& exn) { | ||
PyErr_SetString(PyExc_ValueError, exn.what()); | ||
} catch (const std::ios_base::failure& exn) { | ||
// Unfortunately, in standard C++ we have no way of distinguishing EOF | ||
// from other errors here; be careful with the exception mask | ||
PyErr_SetString(PyExc_IOError, exn.what()); | ||
} catch (const std::out_of_range& exn) { | ||
// Change out_of_range to IndexError | ||
PyErr_SetString(PyExc_IndexError, exn.what()); | ||
} catch (const std::overflow_error& exn) { | ||
PyErr_SetString(PyExc_OverflowError, exn.what()); | ||
} catch (const std::range_error& exn) { | ||
PyErr_SetString(PyExc_ArithmeticError, exn.what()); | ||
} catch (const std::underflow_error& exn) { | ||
PyErr_SetString(PyExc_ArithmeticError, exn.what()); | ||
// The below is the default catch-all case. | ||
} catch (const std::exception& exn) { | ||
PyErr_SetString(PyExc_RuntimeError, exn.what()); | ||
} catch (...) { | ||
PyErr_SetString(PyExc_RuntimeError, "Unknown exception"); | ||
} | ||
} | ||
} // anonymous namespace | ||
""" | ||
cdef void cudf_exception_handler() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters