Skip to content

Commit e8e0660

Browse files
committed
Add test for boost::histogram::func_transform situation.
1 parent f365314 commit e8e0660

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

tests/test_callbacks.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,41 @@
1414

1515
#include <thread>
1616

17+
namespace test_callbacks {
18+
namespace boost_histogram { // See PR #5580
19+
20+
double custom_transform_double(double value) { return value * 3; }
21+
int custom_transform_int(int value) { return value; }
22+
23+
// Derived from
24+
// https://github.com/scikit-hep/boost-histogram/blob/460ef90905d6a8a9e6dd3beddfe7b4b49b364579/include/bh_python/transform.hpp#L68-L85
25+
double apply_custom_transform(const py::object &src, double value) {
26+
using raw_t = double(double);
27+
28+
auto func = py::reinterpret_borrow<py::function>(src);
29+
30+
if (auto cfunc = func.cpp_function()) {
31+
auto c = py::reinterpret_borrow<py::capsule>(PyCFunction_GET_SELF(cfunc.ptr()));
32+
33+
auto rec = c.get_pointer<py::detail::function_record>();
34+
35+
if (rec && rec->is_stateless
36+
&& py::detail::same_type(typeid(raw_t *),
37+
*reinterpret_cast<const std::type_info *>(rec->data[1]))) {
38+
struct capture {
39+
raw_t *f;
40+
};
41+
auto cap = reinterpret_cast<capture *>(&rec->data);
42+
return (*cap->f)(value);
43+
}
44+
return -200;
45+
}
46+
return -100;
47+
}
48+
49+
} // namespace boost_histogram
50+
} // namespace test_callbacks
51+
1752
int dummy_function(int i) { return i + 1; }
1853

1954
TEST_SUBMODULE(callbacks, m) {
@@ -272,4 +307,11 @@ TEST_SUBMODULE(callbacks, m) {
272307
// rec_capsule with nullptr name
273308
py::capsule rec_capsule2(std::malloc(1), [](void *data) { std::free(data); });
274309
m.add_object("custom_function2", PyCFunction_New(custom_def, rec_capsule2.ptr()));
310+
311+
m.def("boost_histogram_custom_transform_double",
312+
test_callbacks::boost_histogram::custom_transform_double);
313+
m.def("boost_histogram_custom_transform_int",
314+
test_callbacks::boost_histogram::custom_transform_int);
315+
m.def("boost_histogram_apply_custom_transform",
316+
test_callbacks::boost_histogram::apply_custom_transform);
275317
}

tests/test_callbacks.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,15 @@ def test_callback_docstring():
234234
m.test_tuple_unpacking.__doc__.strip()
235235
== "test_tuple_unpacking(arg0: Callable) -> object"
236236
)
237+
238+
239+
def test_boost_histogram_apply_custom_transform():
240+
ctd = m.boost_histogram_custom_transform_double
241+
cti = m.boost_histogram_custom_transform_int
242+
apply = m.boost_histogram_apply_custom_transform
243+
assert apply(ctd, 5) == 15
244+
assert apply(cti, 0) == -200
245+
assert apply(None, 0) == -100
246+
assert apply(lambda value: value, 0) == -100
247+
assert apply({}, 0) == -100
248+
assert apply("", 0) == -100

0 commit comments

Comments
 (0)