Skip to content

Commit 3a8d923

Browse files
authored
Fix caster optimization regression introduced in #3650 (#3659)
* 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
1 parent bf7e5f9 commit 3a8d923

File tree

4 files changed

+32
-7
lines changed

4 files changed

+32
-7
lines changed

include/pybind11/detail/internals.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@ struct type_info {
200200
void *get_buffer_data = nullptr;
201201
void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
202202
/* A simple type never occurs as a (direct or indirect) parent
203-
* of a class that makes use of multiple inheritance */
203+
* of a class that makes use of multiple inheritance.
204+
* A type can be simple even if it has non-simple ancestors as long as it has no descendants.
205+
*/
204206
bool simple_type : 1;
205207
/* True if there is no multiple inheritance in this type's inheritance tree */
206208
bool simple_ancestors : 1;

include/pybind11/pybind11.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,13 +1206,14 @@ class generic_type : public object {
12061206
if (rec.bases.size() > 1 || rec.multiple_inheritance) {
12071207
mark_parents_nonsimple(tinfo->type);
12081208
tinfo->simple_ancestors = false;
1209-
tinfo->simple_type = false;
12101209
}
12111210
else if (rec.bases.size() == 1) {
1212-
auto parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
1213-
tinfo->simple_ancestors = parent_tinfo->simple_ancestors;
1214-
// a child of a non-simple type can never be a simple type
1215-
tinfo->simple_type = parent_tinfo->simple_type;
1211+
auto *parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
1212+
assert(parent_tinfo != nullptr);
1213+
bool parent_simple_ancestors = parent_tinfo->simple_ancestors;
1214+
tinfo->simple_ancestors = parent_simple_ancestors;
1215+
// The parent can no longer be a simple type if it has MI and has a child
1216+
parent_tinfo->simple_type = parent_tinfo->simple_type && parent_simple_ancestors;
12161217
}
12171218

12181219
if (rec.module_local) {

tests/test_multiple_inheritance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ TEST_SUBMODULE(multiple_inheritance, m) {
235235
// - functions are get_{base}_{var}, return {var}
236236
struct MVB {
237237
MVB() = default;
238-
MVB(const MVB&) = default;
238+
MVB(const MVB &) = default;
239239
virtual ~MVB() = default;
240240

241241
int b = 1;

tests/test_multiple_inheritance.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,3 +472,25 @@ def test_pr3635_diamond_f():
472472
assert o.get_f_e() == 5
473473

474474
assert o.get_f_f() == 6
475+
476+
477+
def test_python_inherit_from_mi():
478+
"""Tests extending a Python class from a single inheritor of a MI class"""
479+
480+
class PyMVF(m.MVF):
481+
g = 7
482+
483+
def get_g_g(self):
484+
return self.g
485+
486+
o = PyMVF()
487+
488+
assert o.b == 1
489+
assert o.c == 2
490+
assert o.d0 == 3
491+
assert o.d1 == 4
492+
assert o.e == 5
493+
assert o.f == 6
494+
assert o.g == 7
495+
496+
assert o.get_g_g() == 7

0 commit comments

Comments
 (0)