Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 09:02:09

0001 /*
0002     pybind11/detail/exception_translation.h: means to translate C++ exceptions to Python exceptions
0003 
0004     Copyright (c) 2024 The Pybind Development Team.
0005 
0006     All rights reserved. Use of this source code is governed by a
0007     BSD-style license that can be found in the LICENSE file.
0008 */
0009 
0010 #pragma once
0011 
0012 #include "common.h"
0013 #include "internals.h"
0014 
0015 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0016 PYBIND11_NAMESPACE_BEGIN(detail)
0017 
0018 // Apply all the extensions translators from a list
0019 // Return true if one of the translators completed without raising an exception
0020 // itself. Return of false indicates that if there are other translators
0021 // available, they should be tried.
0022 inline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {
0023     auto last_exception = std::current_exception();
0024 
0025     for (auto &translator : translators) {
0026         try {
0027             translator(last_exception);
0028             return true;
0029         } catch (...) {
0030             last_exception = std::current_exception();
0031         }
0032     }
0033     return false;
0034 }
0035 
0036 inline void try_translate_exceptions() {
0037     /* When an exception is caught, give each registered exception
0038         translator a chance to translate it to a Python exception. First
0039         all module-local translators will be tried in reverse order of
0040         registration. If none of the module-locale translators handle
0041         the exception (or there are no module-locale translators) then
0042         the global translators will be tried, also in reverse order of
0043         registration.
0044 
0045         A translator may choose to do one of the following:
0046 
0047         - catch the exception and call py::set_error()
0048             to set a standard (or custom) Python exception, or
0049         - do nothing and let the exception fall through to the next translator, or
0050         - delegate translation to the next translator by throwing a new type of exception.
0051         */
0052 
0053     bool handled = with_internals([&](internals &internals) {
0054         auto &local_exception_translators = get_local_internals().registered_exception_translators;
0055         if (detail::apply_exception_translators(local_exception_translators)) {
0056             return true;
0057         }
0058         auto &exception_translators = internals.registered_exception_translators;
0059         if (detail::apply_exception_translators(exception_translators)) {
0060             return true;
0061         }
0062         return false;
0063     });
0064 
0065     if (!handled) {
0066         set_error(PyExc_SystemError, "Exception escaped from default exception translator!");
0067     }
0068 }
0069 
0070 PYBIND11_NAMESPACE_END(detail)
0071 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)