mirror of https://github.com/pybind/pybind11
Browse Source
* Allow specializations based on callback function return values. * clang-tidy auto fix * Add a test case for function specialization. * Add test for callback function that raises Python exception. * Fix test failures. * style: pre-commit fixes * Add `#define PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS` --------- Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>pull/5297/head
4 changed files with 107 additions and 34 deletions
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
#include <pybind11/functional.h> |
||||
#include <pybind11/pybind11.h> |
||||
|
||||
#include "pybind11_tests.h" |
||||
|
||||
namespace py = pybind11; |
||||
|
||||
namespace { |
||||
|
||||
struct SpecialReturn { |
||||
int value = 99; |
||||
}; |
||||
|
||||
} // namespace
|
||||
|
||||
namespace pybind11 { |
||||
namespace detail { |
||||
namespace type_caster_std_function_specializations { |
||||
|
||||
template <typename... Args> |
||||
struct func_wrapper<SpecialReturn, Args...> : func_wrapper_base { |
||||
using func_wrapper_base::func_wrapper_base; |
||||
SpecialReturn operator()(Args... args) const { |
||||
gil_scoped_acquire acq; |
||||
SpecialReturn result; |
||||
try { |
||||
result = hfunc.f(std::forward<Args>(args)...).template cast<SpecialReturn>(); |
||||
} catch (error_already_set &) { |
||||
result.value += 1; |
||||
} |
||||
result.value += 100; |
||||
return result; |
||||
} |
||||
}; |
||||
|
||||
} // namespace type_caster_std_function_specializations
|
||||
} // namespace detail
|
||||
} // namespace pybind11
|
||||
|
||||
TEST_SUBMODULE(type_caster_std_function_specializations, m) { |
||||
py::class_<SpecialReturn>(m, "SpecialReturn") |
||||
.def(py::init<>()) |
||||
.def_readwrite("value", &SpecialReturn::value); |
||||
m.def("call_callback_with_special_return", |
||||
[](const std::function<SpecialReturn()> &func) { return func(); }); |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
from __future__ import annotations |
||||
|
||||
from pybind11_tests import type_caster_std_function_specializations as m |
||||
|
||||
|
||||
def test_callback_with_special_return(): |
||||
def return_special(): |
||||
return m.SpecialReturn() |
||||
|
||||
def raise_exception(): |
||||
raise ValueError("called raise_exception.") |
||||
|
||||
assert return_special().value == 99 |
||||
assert m.call_callback_with_special_return(return_special).value == 199 |
||||
assert m.call_callback_with_special_return(raise_exception).value == 200 |
Loading…
Reference in new issue