mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Support multiple inheritance from python
This commit allows multiple inheritance of pybind11 classes from
Python, e.g.
class MyType(Base1, Base2):
def __init__(self):
Base1.__init__(self)
Base2.__init__(self)
where Base1 and Base2 are pybind11-exported classes.
This requires collapsing the various builtin base objects
(pybind11_object_56, ...) introduced in 2.1 into a single
pybind11_object of a fixed size; this fixed size object allocates enough
space to contain either a simple object (one base class & small* holder
instance), or a pointer to a new allocation that can contain an
arbitrary number of base classes and holders, with holder size
unrestricted.
* "small" here means having a sizeof() of at most 2 pointers, which is
enough to fit unique_ptr (sizeof is 1 ptr) and shared_ptr (sizeof is 2
ptrs).
To minimize the performance impact, this repurposes
`internals::registered_types_py` to store a vector of pybind-registered
base types. For direct-use pybind types (e.g. the `PyA` for a C++ `A`)
this is simply storing the same thing as before, but now in a vector;
for Python-side inherited types, the map lets us avoid having to do a
base class traversal as long as we've seen the class before. The
change to vector is needed for multiple inheritance: Python types
inheriting from multiple registered bases have one entry per base.
This commit is contained in:
@@ -132,6 +132,16 @@ def test_unique_nodelete():
|
||||
assert cstats.alive() == 1 # Leak, but that's intentional
|
||||
|
||||
|
||||
def test_large_holder():
|
||||
from pybind11_tests import MyObject5
|
||||
o = MyObject5(5)
|
||||
assert o.value == 5
|
||||
cstats = ConstructorStats.get(MyObject5)
|
||||
assert cstats.alive() == 1
|
||||
del o
|
||||
assert cstats.alive() == 0
|
||||
|
||||
|
||||
def test_shared_ptr_and_references():
|
||||
from pybind11_tests.smart_ptr import SharedPtrRef, A
|
||||
|
||||
|
||||
Reference in New Issue
Block a user