Skip to content

Commit

Permalink
Fix caster optimization regression introduced in #3650 (#3659)
Browse files Browse the repository at this point in the history
* Fix optimization bug introduced in #3650

* Add simple Python extension test for MVF

* Improve comments

* Clarify comment

* Clarify another comment

* Add test docstring

* Fix typo
  • Loading branch information
Skylion007 authored Jan 31, 2022
1 parent bf7e5f9 commit 3a8d923
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 7 deletions.
4 changes: 3 additions & 1 deletion include/pybind11/detail/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ struct type_info {
void *get_buffer_data = nullptr;
void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
/* A simple type never occurs as a (direct or indirect) parent
* of a class that makes use of multiple inheritance */
* of a class that makes use of multiple inheritance.
* A type can be simple even if it has non-simple ancestors as long as it has no descendants.
*/
bool simple_type : 1;
/* True if there is no multiple inheritance in this type's inheritance tree */
bool simple_ancestors : 1;
Expand Down
11 changes: 6 additions & 5 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -1206,13 +1206,14 @@ class generic_type : public object {
if (rec.bases.size() > 1 || rec.multiple_inheritance) {
mark_parents_nonsimple(tinfo->type);
tinfo->simple_ancestors = false;
tinfo->simple_type = false;
}
else if (rec.bases.size() == 1) {
auto parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
tinfo->simple_ancestors = parent_tinfo->simple_ancestors;
// a child of a non-simple type can never be a simple type
tinfo->simple_type = parent_tinfo->simple_type;
auto *parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
assert(parent_tinfo != nullptr);
bool parent_simple_ancestors = parent_tinfo->simple_ancestors;
tinfo->simple_ancestors = parent_simple_ancestors;
// The parent can no longer be a simple type if it has MI and has a child
parent_tinfo->simple_type = parent_tinfo->simple_type && parent_simple_ancestors;
}

if (rec.module_local) {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_multiple_inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ TEST_SUBMODULE(multiple_inheritance, m) {
// - functions are get_{base}_{var}, return {var}
struct MVB {
MVB() = default;
MVB(const MVB&) = default;
MVB(const MVB &) = default;
virtual ~MVB() = default;

int b = 1;
Expand Down
22 changes: 22 additions & 0 deletions tests/test_multiple_inheritance.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,25 @@ def test_pr3635_diamond_f():
assert o.get_f_e() == 5

assert o.get_f_f() == 6


def test_python_inherit_from_mi():
"""Tests extending a Python class from a single inheritor of a MI class"""

class PyMVF(m.MVF):
g = 7

def get_g_g(self):
return self.g

o = PyMVF()

assert o.b == 1
assert o.c == 2
assert o.d0 == 3
assert o.d1 == 4
assert o.e == 5
assert o.f == 6
assert o.g == 7

assert o.get_g_g() == 7

0 comments on commit 3a8d923

Please sign in to comment.