Add failing optional test

This commit is contained in:
fatvlady 2020-03-14 15:15:12 +02:00 committed by Wenzel Jakob
parent 8e85fadff2
commit a3daf87d45
2 changed files with 50 additions and 0 deletions

View File

@ -50,6 +50,17 @@ namespace std {
} }
template <template <typename> typename OptionalImpl, typename T>
struct OptionalHolder
{
OptionalHolder() = default;
bool member_initialized() const {
return member && member->initialized;
}
OptionalImpl<T> member = T{};
};
TEST_SUBMODULE(stl, m) { TEST_SUBMODULE(stl, m) {
// test_vector // test_vector
m.def("cast_vector", []() { return std::vector<int>{1}; }); m.def("cast_vector", []() { return std::vector<int>{1}; });
@ -154,6 +165,23 @@ TEST_SUBMODULE(stl, m) {
.def(py::init<>()) .def(py::init<>())
.def(py::init<int>()); .def(py::init<int>());
struct MoveOutDetector
{
MoveOutDetector() = default;
MoveOutDetector(const MoveOutDetector&) = default;
MoveOutDetector(MoveOutDetector&& other) noexcept
: initialized(other.initialized) {
// steal underlying resource
other.initialized = false;
}
bool initialized = true;
};
py::class_<MoveOutDetector>(m, "MoveOutDetector", "Class with move tracking")
.def(py::init<>())
.def_readonly("initialized", &MoveOutDetector::initialized);
#ifdef PYBIND11_HAS_OPTIONAL #ifdef PYBIND11_HAS_OPTIONAL
// test_optional // test_optional
m.attr("has_optional") = true; m.attr("has_optional") = true;
@ -175,6 +203,12 @@ TEST_SUBMODULE(stl, m) {
m.def("nodefer_none_optional", [](std::optional<int>) { return true; }); m.def("nodefer_none_optional", [](std::optional<int>) { return true; });
m.def("nodefer_none_optional", [](py::none) { return false; }); m.def("nodefer_none_optional", [](py::none) { return false; });
using opt_holder = OptionalHolder<std::optional, MoveOutDetector>;
py::class_<opt_holder>(m, "OptionalHolder", "Class with optional member")
.def(py::init<>())
.def_readonly("member", &opt_holder::member)
.def("member_initialized", &opt_holder::member_initialized);
#endif #endif
#ifdef PYBIND11_HAS_EXP_OPTIONAL #ifdef PYBIND11_HAS_EXP_OPTIONAL
@ -195,6 +229,12 @@ TEST_SUBMODULE(stl, m) {
m.def("test_no_assign_exp", [](const exp_opt_no_assign &x) { m.def("test_no_assign_exp", [](const exp_opt_no_assign &x) {
return x ? x->value : 42; return x ? x->value : 42;
}, py::arg_v("x", std::experimental::nullopt, "None")); }, py::arg_v("x", std::experimental::nullopt, "None"));
using opt_exp_holder = OptionalHolder<std::experimental::optional, MoveOutDetector>;
py::class_<opt_exp_holder>(m, "OptionalExpHolder", "Class with optional member")
.def(py::init<>())
.def_readonly("member", &opt_exp_holder::member)
.def("member_initialized", &opt_exp_holder::member_initialized);
#endif #endif
#ifdef PYBIND11_HAS_VARIANT #ifdef PYBIND11_HAS_VARIANT

View File

@ -127,6 +127,11 @@ def test_optional():
assert m.nodefer_none_optional(None) assert m.nodefer_none_optional(None)
holder = m.OptionalHolder()
mvalue = holder.member
assert mvalue.initialized
assert holder.member_initialized()
@pytest.mark.skipif(not hasattr(m, "has_exp_optional"), reason='no <experimental/optional>') @pytest.mark.skipif(not hasattr(m, "has_exp_optional"), reason='no <experimental/optional>')
def test_exp_optional(): def test_exp_optional():
@ -148,6 +153,11 @@ def test_exp_optional():
assert m.test_no_assign_exp(m.NoAssign(43)) == 43 assert m.test_no_assign_exp(m.NoAssign(43)) == 43
pytest.raises(TypeError, m.test_no_assign_exp, 43) pytest.raises(TypeError, m.test_no_assign_exp, 43)
holder = m.OptionalExpHolder()
mvalue = holder.member
assert mvalue.initialized
assert holder.member_initialized()
@pytest.mark.skipif(not hasattr(m, "load_variant"), reason='no <variant>') @pytest.mark.skipif(not hasattr(m, "load_variant"), reason='no <variant>')
def test_variant(doc): def test_variant(doc):