diff --git a/README_smart_holder.rst b/README_smart_holder.rst index baf7b8ff0..cae40ff12 100644 --- a/README_smart_holder.rst +++ b/README_smart_holder.rst @@ -164,6 +164,17 @@ of interest have made the switch, because then the code will continue to work in either mode. +Using py::classh but with fallback to classic pybind11 +------------------------------------------------------ + +This could be viewed as super-conservative mode, for situations in which +compatibility with classic pybind11 (without smart_holder) is needed for +some period of time. The main idea is to enable use of ``py::classh`` +and the associated ``PYBIND11_SMART_HOLDER_TYPE_CASTERS`` macro while +still being able to build the same code with classic pybind11. Please see +tests/test_classh_mock.cpp for an example. + + Trampolines and std::unique_ptr ------------------------------- diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1a1ca45da..3a7fbffad 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -112,6 +112,7 @@ set(PYBIND11_TEST_FILES test_class_sh_trampoline_unique_ptr.cpp test_class_sh_unique_ptr_member.cpp test_class_sh_virtual_py_cpp_mix.cpp + test_classh_mock.cpp test_constants_and_functions.cpp test_copy_move.cpp test_custom_type_casters.cpp diff --git a/tests/test_classh_mock.cpp b/tests/test_classh_mock.cpp new file mode 100644 index 000000000..af016c7f8 --- /dev/null +++ b/tests/test_classh_mock.cpp @@ -0,0 +1,46 @@ +#include "pybind11_tests.h" + +// The main purpose of this test is to ensure the suggested BOILERPLATE code block below is +// correct. + +// Copy this block of code into your project. +// Replace FOOEXT with the name of your project. +// BOILERPLATE BEGIN +#ifdef FOOEXT_USING_PYBIND11_SMART_HOLDER +# include +#else +# include +PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +template +using classh = class_; +PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) +# ifndef PYBIND11_SMART_HOLDER_TYPE_CASTERS +# define PYBIND11_SMART_HOLDER_TYPE_CASTERS(...) +# endif +# ifndef PYBIND11_TYPE_CASTER_BASE_HOLDER +# define PYBIND11_TYPE_CASTER_BASE_HOLDER(...) +# endif +#endif +// BOILERPLATE END + +namespace { +struct Foo0 {}; +struct Foo1 {}; +struct Foo2 {}; +} // namespace + +PYBIND11_TYPE_CASTER_BASE_HOLDER(Foo1, std::shared_ptr) +PYBIND11_SMART_HOLDER_TYPE_CASTERS(Foo2) + +TEST_SUBMODULE(classh_mock, m) { + // Uses std::unique_ptr as holder in conservative mode, py::smart_holder in progressive + // mode (if available). + py::class_(m, "Foo0").def(py::init<>()); + + // Always uses std::shared_ptr as holder. + py::class_>(m, "Foo1").def(py::init<>()); + + // Uses py::smart_holder if available, or std::unique_ptr if only pybind11 classic is + // available. + py::classh(m, "Foo2").def(py::init<>()); +} diff --git a/tests/test_classh_mock.py b/tests/test_classh_mock.py new file mode 100644 index 000000000..2c1d48754 --- /dev/null +++ b/tests/test_classh_mock.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +from pybind11_tests import classh_mock as m + + +def test_foobar(): + # Not really testing anything in particular. The main purpose of this test is to ensure the + # suggested BOILERPLATE code block in test_classh_mock.cpp is correct. + assert m.Foo0() + assert m.Foo1() + assert m.Foo2()