Skip to content

Commit afe0c0f

Browse files
pybind11_abseil authorscopybara-github
authored andcommitted
New function CallAndCatchPybind11Exceptions, to convert all pybind11 exceptions into absl::Status.
PiperOrigin-RevId: 858213368
1 parent 54b34dd commit afe0c0f

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

pybind11_abseil/compat/BUILD

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,13 @@ pybind_library(
4444
"@com_google_absl//absl/status",
4545
],
4646
)
47+
48+
pybind_library(
49+
name = "status_from_cpp_exc",
50+
hdrs = ["status_from_cpp_exc.h"],
51+
visibility = ["//visibility:public"],
52+
deps = [
53+
":status_from_py_exc",
54+
"@com_google_absl//absl/log:check",
55+
],
56+
)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef PYBIND11_ABSEIL_COMPAT_STATUS_FROM_CPP_EXC_H_
2+
#define PYBIND11_ABSEIL_COMPAT_STATUS_FROM_CPP_EXC_H_
3+
4+
#include "absl/log/check.h"
5+
#include "third_party/pybind11/include/pybind11/pytypes.h"
6+
#include "pybind11_abseil/compat/status_from_py_exc.h"
7+
8+
namespace pybind11_abseil::compat {
9+
10+
// This function is intended for C++ code which uses pybind11 code,
11+
// from a C++ thread of from an embedded Python interpreter.
12+
//
13+
// It executes the given function, catches potential C++ exceptions
14+
// and converts them to absl::Status.
15+
//
16+
// The status code depends on the exception type (see
17+
// GetPyExceptionStatusCodeMap).
18+
// The status message always starts with the Python exception class name.
19+
// The Python traceback is not preserved.
20+
template <typename Func>
21+
inline decltype(std::declval<Func>()()) CallAndCatchPybind11Exceptions(
22+
Func&& func) {
23+
DCHECK(PyGILState_Check());
24+
try {
25+
return std::forward<Func>(func)();
26+
} catch (pybind11::error_already_set& e) {
27+
e.restore();
28+
return StatusFromPyExcGivenErrOccurred();
29+
} catch (pybind11::builtin_exception& e) {
30+
e.set_error();
31+
return StatusFromPyExcGivenErrOccurred();
32+
}
33+
}
34+
35+
} // namespace pybind11_abseil::compat
36+
37+
#endif // PYBIND11_ABSEIL_COMPAT_STATUS_FROM_CPP_EXC_H_

0 commit comments

Comments
 (0)