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 @@ |
|||||||
|
#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 @@ |
|||||||
|
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