LCOV - code coverage report
Current view: top level - python - except.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 28 28 100.0 %
Date: 2024-11-24 01:48:31 Functions: 19 19 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : 
       6             : #include "scipp/core/except.h"
       7             : #include "pybind11.h"
       8             : #include "scipp/dataset/except.h"
       9             : #include "scipp/units/except.h"
      10             : #include "scipp/variable/except.h"
      11             : 
      12             : namespace py = pybind11;
      13             : 
      14             : namespace {
      15             : /// Translate an exception into a standard Python exception.
      16             : template <class CppException, class PyException>
      17          12 : void register_with_builtin_exception(const PyException &py_exception) {
      18             :   // Pybind11 does not like it when the lambda captures something,
      19             :   // so 'pass' py_exception via a static variable.
      20          12 :   static auto pyexc = py_exception;
      21        4454 :   py::register_exception_translator([](std::exception_ptr p) {
      22             :     try {
      23       72097 :       if (p)
      24      144194 :         std::rethrow_exception(p);
      25       76539 :     } catch (const CppException &e) {
      26        4442 :       PyErr_SetString(pyexc, e.what());
      27             :     }
      28             :   });
      29          12 : }
      30             : 
      31             : template <class CppException>
      32          30 : void register_exception(py::handle scope, const char *name, py::handle base,
      33             :                         const char *doc) {
      34          30 :   auto exc = py::register_exception<CppException>(scope, name, base);
      35          30 :   exc.doc() = doc;
      36          30 : }
      37             : } // namespace
      38             : 
      39           3 : void init_exceptions(py::module &m) {
      40             :   using namespace scipp;
      41             : 
      42           3 :   register_exception<except::BinEdgeError>(
      43             :       m, "BinEdgeError", PyExc_RuntimeError,
      44             :       "Inappropriate bin-edge coordinate.");
      45           3 :   register_exception<except::BinnedDataError>(m, "BinnedDataError",
      46             :                                               PyExc_RuntimeError,
      47             :                                               "Incorrect use of binned data.");
      48           3 :   register_exception<except::CoordMismatchError>(
      49             :       m, "CoordError", PyExc_RuntimeError,
      50             :       "Bad coordinate values or mismatching coordinates.");
      51           3 :   register_exception<except::DataArrayError>(
      52             :       m, "DataArrayError", PyExc_RuntimeError,
      53             :       "Incorrect use of scipp.DataArray.");
      54           3 :   register_exception<except::DatasetError>(
      55             :       m, "DatasetError", PyExc_RuntimeError, "Incorrect use of scipp.Dataset.");
      56           3 :   register_exception<except::DimensionError>(
      57             :       m, "DimensionError", PyExc_RuntimeError,
      58             :       "Inappropriate dimension labels and/or shape.");
      59           3 :   register_exception<except::TypeError>(m, "DTypeError", PyExc_TypeError,
      60             :                                         "Inappropriate dtype.");
      61           3 :   register_exception<except::UnitError>(m, "UnitError", PyExc_RuntimeError,
      62             :                                         "Inappropriate unit.");
      63           3 :   register_exception<except::VariableError>(m, "VariableError",
      64             :                                             PyExc_RuntimeError,
      65             :                                             "Incorrect use of scipp.Variable.");
      66           3 :   register_exception<except::VariancesError>(
      67             :       m, "VariancesError", PyExc_RuntimeError,
      68             :       "Variances used where they are not supported or not used where they are "
      69             :       "required.");
      70             : 
      71           3 :   register_with_builtin_exception<except::SizeError>(PyExc_ValueError);
      72           3 :   register_with_builtin_exception<except::SliceError>(PyExc_IndexError);
      73           3 :   register_with_builtin_exception<except::NotFoundError>(PyExc_KeyError);
      74           3 :   register_with_builtin_exception<except::NotImplementedError>(
      75             :       PyExc_NotImplementedError);
      76           3 : }

Generated by: LCOV version 1.14