Skip to content

Commit d1960a1

Browse files
committed
Add minimal_real_caster (from PR pybind#3862) to test_async, test_buffers
1 parent 5c7e77c commit d1960a1

File tree

4 files changed

+99
-0
lines changed

4 files changed

+99
-0
lines changed

tests/test_async.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,48 @@
99

1010
#include "pybind11_tests.h"
1111

12+
namespace mrc_ns { // minimal real caster
13+
14+
struct minimal_real_caster;
15+
16+
struct type_mrc {
17+
int value = -9999;
18+
};
19+
20+
struct minimal_real_caster {
21+
static constexpr auto name = py::detail::const_name<type_mrc>();
22+
23+
static py::handle
24+
cast(type_mrc const &src, py::return_value_policy /*policy*/, py::handle /*parent*/) {
25+
return py::int_(src.value + 1010).release();
26+
}
27+
28+
// Maximizing simplicity. This will go terribly wrong for other arg types.
29+
template <typename>
30+
using cast_op_type = const type_mrc &;
31+
32+
// NOLINTNEXTLINE(google-explicit-constructor)
33+
operator type_mrc const &() {
34+
static type_mrc obj;
35+
obj.value = 11;
36+
return obj;
37+
}
38+
39+
bool load(py::handle src, bool /*convert*/) {
40+
// Only accepts str, but the value is ignored.
41+
return py::isinstance<py::str>(src);
42+
}
43+
};
44+
45+
} // namespace mrc_ns
46+
47+
namespace pybind11 {
48+
namespace detail {
49+
template <>
50+
struct type_caster<mrc_ns::type_mrc> : mrc_ns::minimal_real_caster {};
51+
} // namespace detail
52+
} // namespace pybind11
53+
1254
TEST_SUBMODULE(async_module, m) {
1355
struct DoesNotSupportAsync {};
1456
py::class_<DoesNotSupportAsync>(m, "DoesNotSupportAsync").def(py::init<>());
@@ -22,4 +64,6 @@ TEST_SUBMODULE(async_module, m) {
2264
f.attr("set_result")(5);
2365
return f.attr("__await__")();
2466
});
67+
m.def("type_mrc_to_python", []() { return mrc_ns::type_mrc{101}; });
68+
m.def("type_mrc_from_python", [](const mrc_ns::type_mrc &obj) { return obj.value + 100; });
2569
}

tests/test_async.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,8 @@ def test_await(event_loop):
2222
def test_await_missing(event_loop):
2323
with pytest.raises(TypeError):
2424
event_loop.run_until_complete(get_await_result(m.DoesNotSupportAsync()))
25+
26+
27+
def test_mrc():
28+
assert m.type_mrc_to_python() == 1111
29+
assert m.type_mrc_from_python("ignored") == 111

tests/test_buffers.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,48 @@
1212
#include "constructor_stats.h"
1313
#include "pybind11_tests.h"
1414

15+
namespace mrc_ns { // minimal real caster
16+
17+
struct minimal_real_caster;
18+
19+
struct type_mrc {
20+
int value = -9999;
21+
};
22+
23+
struct minimal_real_caster {
24+
static constexpr auto name = py::detail::const_name<type_mrc>();
25+
26+
static py::handle
27+
cast(type_mrc const &src, py::return_value_policy /*policy*/, py::handle /*parent*/) {
28+
return py::int_(src.value + 2020).release();
29+
}
30+
31+
// Maximizing simplicity. This will go terribly wrong for other arg types.
32+
template <typename>
33+
using cast_op_type = const type_mrc &;
34+
35+
// NOLINTNEXTLINE(google-explicit-constructor)
36+
operator type_mrc const &() {
37+
static type_mrc obj;
38+
obj.value = 22;
39+
return obj;
40+
}
41+
42+
bool load(py::handle src, bool /*convert*/) {
43+
// Only accepts str, but the value is ignored.
44+
return py::isinstance<py::str>(src);
45+
}
46+
};
47+
48+
} // namespace mrc_ns
49+
50+
namespace pybind11 {
51+
namespace detail {
52+
template <>
53+
struct type_caster<mrc_ns::type_mrc> : mrc_ns::minimal_real_caster {};
54+
} // namespace detail
55+
} // namespace pybind11
56+
1557
TEST_SUBMODULE(buffers, m) {
1658
// test_from_python / test_to_python:
1759
class Matrix {
@@ -221,4 +263,7 @@ TEST_SUBMODULE(buffers, m) {
221263
});
222264

223265
m.def("get_buffer_info", [](const py::buffer &buffer) { return buffer.request(); });
266+
267+
m.def("type_mrc_to_python", []() { return mrc_ns::type_mrc{202}; });
268+
m.def("type_mrc_from_python", [](const mrc_ns::type_mrc &obj) { return obj.value + 200; });
224269
}

tests/test_buffers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,8 @@ def test_ctypes_from_buffer():
161161
assert cinfo.shape == pyinfo.shape
162162
assert cinfo.strides == pyinfo.strides
163163
assert not cinfo.readonly
164+
165+
166+
def test_mrc():
167+
assert m.type_mrc_to_python() == 1111
168+
assert m.type_mrc_from_python("ignored") == 111

0 commit comments

Comments
 (0)