You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Create a module_internals struct
Since we now have two things that are going to be module local, it felt
correct to add a struct to manage them.
* Add local exception translators
These are added via the register_local_exception_translator function
and are then applied before the global translators
* Add unit tests to show the local exception translator works
* Fix a bug in the unit test with the string value of KeyError
* Fix a formatting issue
* Rename registered_local_types_cpp()
Rename it to get_registered_local_types_cpp() to disambiguate from the
new member of module_internals
* Add additional comments to new local exception code path
* Add a register_local_exception function
* Add additional unit tests for register_local_exception
* Use get_local_internals like get_internals
* Update documentation for new local exception feature
* Add back a missing space
* Clean-up some issues in the docs
* Remove the code duplication when translating exceptions
Separated out the exception processing into a standalone function in the
details namespace.
Clean-up some comments as per PR notes as well
* Remove the code duplication in register_exception
* Cleanup some formatting things caught by clang-format
* Remove the templates from exception translators
But I added a using declaration to alias the type.
* Remove the extra local from local_internals variable names
* Add an extra explanatory comment to local_internals
* Fix a typo in the code
Then `PyExp` can be caught both as `PyExp` and `RuntimeError`.
98
107
99
108
The class objects of the built-in Python exceptions are listed in the Python
100
109
documentation on `Standard Exceptions <https://docs.python.org/3/c-api/exceptions.html#standard-exceptions>`_.
101
110
The default base class is `PyExc_Exception`.
102
111
103
-
When more advanced exception translation is needed, the function
104
-
``py::register_exception_translator(translator)`` can be used to register
112
+
When more advanced exception translation is needed, the functions
113
+
``py::register_exception_translator(translator)`` and
114
+
``py::register_local_exception_translator(translator)`` can be used to register
105
115
functions that can translate arbitrary exception types (and which may include
106
-
additional logic to do so). The function takes a stateless callable (e.g. a
116
+
additional logic to do so). The functions takes a stateless callable (e.g. a
107
117
function pointer or a lambda function without captured variables) with the call
108
118
signature ``void(std::exception_ptr)``.
109
119
110
120
When a C++ exception is thrown, the registered exception translators are tried
111
121
in reverse order of registration (i.e. the last registered translator gets the
112
-
first shot at handling the exception).
122
+
first shot at handling the exception). All local translators will be tried
123
+
before a global translator is tried.
113
124
114
125
Inside the translator, ``std::rethrow_exception`` should be used within
115
126
a try block to re-throw the exception. One or more catch clauses to catch
@@ -168,6 +179,53 @@ section.
168
179
with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI boundaries need to be explicitly exported, as exercised in ``tests/test_exceptions.h``.
169
180
See also: "Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_.
170
181
182
+
183
+
Local vs Global Exception Translators
184
+
=====================================
185
+
186
+
When a global exception translator is registered, it will be applied across all
187
+
modules in the reverse order of registration. This can create behavior where the
188
+
order of module import influences how exceptions are translated.
0 commit comments