diff --git a/tests/test_cpp_base_py_derived.cpp b/tests/test_cpp_base_py_derived.cpp new file mode 100644 index 00000000000..cbc117f44a0 --- /dev/null +++ b/tests/test_cpp_base_py_derived.cpp @@ -0,0 +1,57 @@ +// pybind11 equivalent of Boost.Python test: +// https://github.com/rwgk/rwgk_tbx/blob/6c9a6d6bc72d5c1b8609724433259c5b47178680/cpp_base_py_derived_ext.cpp +// See also: https://github.com/pybind/pybind11/issues/1333 (this was the starting point) + +#include "pybind11_tests.h" + +namespace pybind11_tests { +namespace cpp_base_py_derived { + +struct base { + base() : base_num(100) {} + + virtual int get_num() const { return base_num; } + + virtual std::shared_ptr clone() const { + return std::shared_ptr(new base(150)); + } + + virtual ~base() = default; + + private: + explicit base(int num) : base_num(num) {} + int base_num; +}; + +inline int get_num(std::shared_ptr b) { return b->get_num(); } + +inline int clone_get_num(std::shared_ptr b) { + std::shared_ptr c = b->clone(); + return (b->get_num() + 3) * 1000 + (c->get_num() + 7); +} + +struct base_trampoline : public base { + using base::base; + + int get_num() const override { + PYBIND11_OVERRIDE(int, base, get_num); + } + + std::shared_ptr clone() const override { + PYBIND11_OVERRIDE(std::shared_ptr, base, clone); + } +}; + +TEST_SUBMODULE(cpp_base_py_derived, m) { + py::class_>(m, "base") + .def(py::init<>()) + .def("get_num", &base::get_num) + .def("clone", &base::clone) + ; + + m.def("get_num", get_num); + m.def("clone_get_num", clone_get_num); +} + +} // namespace cpp_base_py_derived +} // namespace pybind11_tests diff --git a/tests/test_cpp_base_py_derived.py b/tests/test_cpp_base_py_derived.py new file mode 100644 index 00000000000..3a36c81fe91 --- /dev/null +++ b/tests/test_cpp_base_py_derived.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# pybind11 equivalent of Boost.Python test: +# https://github.com/rwgk/rwgk_tbx/blob/6c9a6d6bc72d5c1b8609724433259c5b47178680/tst_cpp_base_py_derived.py +# See also: https://github.com/pybind/pybind11/issues/1333 (this was the starting point) +import pytest + +from pybind11_tests import cpp_base_py_derived as m + + +class drvd(m.base): + + def __init__(self, _num = 200): + super().__init__() + self._drvd_num = _num + + def get_num(self): + return self._drvd_num + + def clone(self): + return drvd(250) + + +def test_base(): + b = m.base() + assert b.get_num() == 100 + m.get_num(b) == 100 + bc = b.clone() + assert bc.get_num() == 150 + assert m.clone_get_num(b) == 103157 + + +def test_drvd(): + d = drvd() + assert d.get_num() == 200 + assert m.get_num(d) == 200 + dc = d.clone() + assert dc.get_num() == 250 + assert m.clone_get_num(d) == 203257