348337916dbd8ff259df61be51bee13ecf0ba979
[gem5.git] / ext / pybind11 / docs / advanced / exceptions.rst
1 Exceptions
2 ##########
3
4 Built-in exception translation
5 ==============================
6
7 When C++ code invoked from Python throws an ``std::exception``, it is
8 automatically converted into a Python ``Exception``. pybind11 defines multiple
9 special exception classes that will map to different types of Python
10 exceptions:
11
12 .. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
13
14 +--------------------------------------+------------------------------+
15 | C++ exception type | Python exception type |
16 +======================================+==============================+
17 | :class:`std::exception` | ``RuntimeError`` |
18 +--------------------------------------+------------------------------+
19 | :class:`std::bad_alloc` | ``MemoryError`` |
20 +--------------------------------------+------------------------------+
21 | :class:`std::domain_error` | ``ValueError`` |
22 +--------------------------------------+------------------------------+
23 | :class:`std::invalid_argument` | ``ValueError`` |
24 +--------------------------------------+------------------------------+
25 | :class:`std::length_error` | ``ValueError`` |
26 +--------------------------------------+------------------------------+
27 | :class:`std::out_of_range` | ``ValueError`` |
28 +--------------------------------------+------------------------------+
29 | :class:`std::range_error` | ``ValueError`` |
30 +--------------------------------------+------------------------------+
31 | :class:`pybind11::stop_iteration` | ``StopIteration`` (used to |
32 | | implement custom iterators) |
33 +--------------------------------------+------------------------------+
34 | :class:`pybind11::index_error` | ``IndexError`` (used to |
35 | | indicate out of bounds |
36 | | accesses in ``__getitem__``, |
37 | | ``__setitem__``, etc.) |
38 +--------------------------------------+------------------------------+
39 | :class:`pybind11::value_error` | ``ValueError`` (used to |
40 | | indicate wrong value passed |
41 | | in ``container.remove(...)`` |
42 +--------------------------------------+------------------------------+
43 | :class:`pybind11::key_error` | ``KeyError`` (used to |
44 | | indicate out of bounds |
45 | | accesses in ``__getitem__``, |
46 | | ``__setitem__`` in dict-like |
47 | | objects, etc.) |
48 +--------------------------------------+------------------------------+
49 | :class:`pybind11::error_already_set` | Indicates that the Python |
50 | | exception flag has already |
51 | | been initialized |
52 +--------------------------------------+------------------------------+
53
54 When a Python function invoked from C++ throws an exception, it is converted
55 into a C++ exception of type :class:`error_already_set` whose string payload
56 contains a textual summary.
57
58 There is also a special exception :class:`cast_error` that is thrown by
59 :func:`handle::call` when the input arguments cannot be converted to Python
60 objects.
61
62 Registering custom translators
63 ==============================
64
65 If the default exception conversion policy described above is insufficient,
66 pybind11 also provides support for registering custom exception translators.
67 To register a simple exception conversion that translates a C++ exception into
68 a new Python exception using the C++ exception's ``what()`` method, a helper
69 function is available:
70
71 .. code-block:: cpp
72
73 py::register_exception<CppExp>(module, "PyExp");
74
75 This call creates a Python exception class with the name ``PyExp`` in the given
76 module and automatically converts any encountered exceptions of type ``CppExp``
77 into Python exceptions of type ``PyExp``.
78
79 When more advanced exception translation is needed, the function
80 ``py::register_exception_translator(translator)`` can be used to register
81 functions that can translate arbitrary exception types (and which may include
82 additional logic to do so). The function takes a stateless callable (e.g. a
83 function pointer or a lambda function without captured variables) with the call
84 signature ``void(std::exception_ptr)``.
85
86 When a C++ exception is thrown, the registered exception translators are tried
87 in reverse order of registration (i.e. the last registered translator gets the
88 first shot at handling the exception).
89
90 Inside the translator, ``std::rethrow_exception`` should be used within
91 a try block to re-throw the exception. One or more catch clauses to catch
92 the appropriate exceptions should then be used with each clause using
93 ``PyErr_SetString`` to set a Python exception or ``ex(string)`` to set
94 the python exception to a custom exception type (see below).
95
96 To declare a custom Python exception type, declare a ``py::exception`` variable
97 and use this in the associated exception translator (note: it is often useful
98 to make this a static declaration when using it inside a lambda expression
99 without requiring capturing).
100
101
102 The following example demonstrates this for a hypothetical exception classes
103 ``MyCustomException`` and ``OtherException``: the first is translated to a
104 custom python exception ``MyCustomError``, while the second is translated to a
105 standard python RuntimeError:
106
107 .. code-block:: cpp
108
109 static py::exception<MyCustomException> exc(m, "MyCustomError");
110 py::register_exception_translator([](std::exception_ptr p) {
111 try {
112 if (p) std::rethrow_exception(p);
113 } catch (const MyCustomException &e) {
114 exc(e.what());
115 } catch (const OtherException &e) {
116 PyErr_SetString(PyExc_RuntimeError, e.what());
117 }
118 });
119
120 Multiple exceptions can be handled by a single translator, as shown in the
121 example above. If the exception is not caught by the current translator, the
122 previously registered one gets a chance.
123
124 If none of the registered exception translators is able to handle the
125 exception, it is handled by the default converter as described in the previous
126 section.
127
128 .. seealso::
129
130 The file :file:`tests/test_exceptions.cpp` contains examples
131 of various custom exception translators and custom exception types.
132
133 .. note::
134
135 You must call either ``PyErr_SetString`` or a custom exception's call
136 operator (``exc(string)``) for every exception caught in a custom exception
137 translator. Failure to do so will cause Python to crash with ``SystemError:
138 error return without exception set``.
139
140 Exceptions that you do not plan to handle should simply not be caught, or
141 may be explicity (re-)thrown to delegate it to the other,
142 previously-declared existing exception translators.