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
I am having trouble using a class as both an exception and a value:
struct Error : public std::runtime_error {
using std::runtime_error::runtime_error;
};
class ErrorHandler {
virtual void handle(const Error& error) = 0;
};
class Service {
void doSync() { throw Error(); }
void doAsync(ErrorHandler& handler) { handler.handle(Error()); }
};
class PyErrorHandler : public ErrorHandler {
using ErrorHandler::ErrorHandler;
void handle(const Error& error) override {
PYBIND11_OVERLOAD_PURE(void, ErrorHandler, handle, error);
}
};
PYBIND11_MODULE(something, module) {
py::class_<ErrorHandler, PyErrorHandler>(module, "ErrorHandler");
py::class_<Service>(module, "Service")
.def("doSync", &Service::doSync)
.def("doAsync", &Service::doAsync);
py::register_exception<Error>(module, "Error");
}
service = something.Service()
try:
service.doSync()
except something.Error as error:
print(error)
class ErrorHandler(something.ErrorHandler):
def handle(self, error):
print(error)
service.doAsync(ErrorHandler())
Pybind11 fails to call the python handler from c++ with RuntimeError: make_tuple(): unable to convert arguments to Python object.
If I use py::class_<Error>(module, "Error") instead of register_exception, the Error cannot be caught when calling doSync anymore: TypeError: catching classes that do not inherit from BaseException is not allowed.
The workaround I had to use was to recreate a python error instance in PyErrorHandler::handle: PYBIND11_OVERLOAD_PURE(void, ErrorHandler, handle, py::module_::import("something").attr("Error")(error.what()));
Is there an other way?
The text was updated successfully, but these errors were encountered:
mvoelkle-cern
changed the title
[QUESTION]
[QUESTION] Using a class as both an exception and a value
Mar 3, 2021
There's a bit of a disconnect between classes and exception types, indeed, so I do wonder if there's much you can do about this.
One solution could be to have a custom caster, which would solve your initial issue (register_exception seems to not register the created exception type with pybind11, such that the standard caster doesn't work).
Hello,
I am having trouble using a class as both an exception and a value:
Pybind11 fails to call the python handler from c++ with
RuntimeError: make_tuple(): unable to convert arguments to Python object
.If I use
py::class_<Error>(module, "Error")
instead ofregister_exception
, the Error cannot be caught when calling doSync anymore:TypeError: catching classes that do not inherit from BaseException is not allowed
.The workaround I had to use was to recreate a python error instance in PyErrorHandler::handle:
PYBIND11_OVERLOAD_PURE(void, ErrorHandler, handle, py::module_::import("something").attr("Error")(error.what()));
Is there an other way?
The text was updated successfully, but these errors were encountered: