From c9a56ac21bd830304df990d8d9667cd7e3b53f90 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 25 Jul 2023 16:15:39 -0700 Subject: [PATCH] Equivalent of https://github.com/google/clif/commit/5718e4d0807fd3b6a8187dde140069120b81ecef --- tests/CMakeLists.txt | 1 + tests/test_python_multiple_inheritance.cpp | 45 ++++++++++++++++++++++ tests/test_python_multiple_inheritance.py | 39 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 tests/test_python_multiple_inheritance.cpp create mode 100644 tests/test_python_multiple_inheritance.py diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 80ee9c1f1..d68067df6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -144,6 +144,7 @@ set(PYBIND11_TEST_FILES test_opaque_types test_operator_overloading test_pickling + test_python_multiple_inheritance test_pytypes test_sequences_and_iterators test_smart_ptr diff --git a/tests/test_python_multiple_inheritance.cpp b/tests/test_python_multiple_inheritance.cpp new file mode 100644 index 000000000..e3a66fb84 --- /dev/null +++ b/tests/test_python_multiple_inheritance.cpp @@ -0,0 +1,45 @@ +#include "pybind11_tests.h" + +namespace test_python_multiple_inheritance { + +// Copied from: +// https://github.com/google/clif/blob/5718e4d0807fd3b6a8187dde140069120b81ecef/clif/testing/python_multiple_inheritance.h + +struct CppBase { + CppBase(int value) : base_value(value) {} + int get_base_value() const { return base_value; } + void reset_base_value(int new_value) { base_value = new_value; } + +private: + int base_value; +}; + +struct CppDrvd : CppBase { + CppDrvd(int value) : CppBase(value), drvd_value(value * 3) {} + int get_drvd_value() const { return drvd_value; } + void reset_drvd_value(int new_value) { drvd_value = new_value; } + + int get_base_value_from_drvd() const { return get_base_value(); } + void reset_base_value_from_drvd(int new_value) { reset_base_value(new_value); } + +private: + int drvd_value; +}; + +} // namespace test_python_multiple_inheritance + +TEST_SUBMODULE(python_multiple_inheritance, m) { + using namespace test_python_multiple_inheritance; + + py::class_(m, "CppBase") + .def(py::init()) + .def("get_base_value", &CppBase::get_base_value) + .def("reset_base_value", &CppBase::reset_base_value); + + py::class_(m, "CppDrvd") + .def(py::init()) + .def("get_drvd_value", &CppDrvd::get_drvd_value) + .def("reset_drvd_value", &CppDrvd::reset_drvd_value) + .def("get_base_value_from_drvd", &CppDrvd::get_base_value_from_drvd) + .def("reset_base_value_from_drvd", &CppDrvd::reset_base_value_from_drvd); +} diff --git a/tests/test_python_multiple_inheritance.py b/tests/test_python_multiple_inheritance.py new file mode 100644 index 000000000..57c196030 --- /dev/null +++ b/tests/test_python_multiple_inheritance.py @@ -0,0 +1,39 @@ +# Adapted from: +# https://github.com/google/clif/blob/5718e4d0807fd3b6a8187dde140069120b81ecef/clif/testing/python/python_multiple_inheritance_test.py + +from pybind11_tests import python_multiple_inheritance as m + + +class PC(m.CppBase): + pass + + +class PPCCInit(PC, m.CppDrvd): + def __init__(self, value): + PC.__init__(self, value) + m.CppDrvd.__init__(self, value + 1) + + +def test_PC(): + d = PC(11) + assert d.get_base_value() == 11 + d.reset_base_value(13) + assert d.get_base_value() == 13 + + +def test_PPCCInit(): + d = PPCCInit(11) + assert d.get_drvd_value() == 36 + d.reset_drvd_value(55) + assert d.get_drvd_value() == 55 + + # CppBase is initialized and used when CppBase methods are called, but + # CppDrvd is used when CppDrvd methods are called. + assert d.get_base_value() == 11 + assert d.get_base_value_from_drvd() == 12 + d.reset_base_value(20) + assert d.get_base_value() == 20 + assert d.get_base_value_from_drvd() == 12 + d.reset_base_value_from_drvd(30) + assert d.get_base_value() == 20 + assert d.get_base_value_from_drvd() == 30