diff --git a/tests/test_unique_ptr_member.cpp b/tests/test_unique_ptr_member.cpp new file mode 100644 index 000000000..96edf77c5 --- /dev/null +++ b/tests/test_unique_ptr_member.cpp @@ -0,0 +1,53 @@ +#include "pybind11_tests.h" + +#include + +namespace pybind11_tests { +namespace unique_ptr_member { + +class pointee { // NOT copyable. + public: + pointee() = default; + + int get_int() const { return 213; } + + private: + pointee(const pointee &) = delete; + pointee(pointee &&) = delete; + pointee &operator=(const pointee &) = delete; + pointee &operator=(pointee &&) = delete; +}; + +class ptr_owner { + public: + explicit ptr_owner(std::unique_ptr ptr) : ptr_(std::move(ptr)) {} + + private: + std::unique_ptr ptr_; +}; + +// Just to have a minimal example of a typical C++ pattern. +inline int cpp_pattern() { + auto obj = std::unique_ptr(new pointee); + int result = (obj ? 10 : 0); + ptr_owner owner(std::move(obj)); + result += (obj ? 1 : 0); + return result; +} + +TEST_SUBMODULE(unique_ptr_member, m) { + m.def("cpp_pattern", cpp_pattern); + + py::class_(m, "pointee") + .def(py::init<>()) + .def("get_int", &pointee::get_int); + + py::class_(m, "ptr_owner") +#ifdef FEAT_UNIQUE_PTR_ARG + .def(py::init>(), py::arg("ptr")) +#endif + ; +} + +} // namespace unique_ptr_member +} // namespace pybind11_tests diff --git a/tests/test_unique_ptr_member.py b/tests/test_unique_ptr_member.py new file mode 100644 index 000000000..121b8ef05 --- /dev/null +++ b/tests/test_unique_ptr_member.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +import pytest + +from pybind11_tests import unique_ptr_member as m + + +def test_cpp_pattern(): + res = m.cpp_pattern() + assert res == 10 + + +def test_pointee_and_ptr_owner(): + obj = m.pointee() + assert obj.get_int() == 213 + m.ptr_owner(obj) + with pytest.raises(ValueError) as exc_info: + obj.get_int() + assert str(exc_info.value).startswith("Missing value for wrapped C++ type ")