@@ -85,6 +85,34 @@ inline PyTypeObject *make_static_property_type() {
8585
8686#endif // PYPY
8787
88+ /* * Inheriting from multiple C++ types in Python is not supported -- set an error instead.
89+ A Python definition (`class C(A, B): pass`) will call `tp_new` so we check for multiple
90+ C++ bases here. On the other hand, C++ type definitions (`py::class_<C, A, B>(m, "C")`)
91+ don't not use `tp_new` and will not trigger this error. */
92+ extern " C" inline PyObject *pybind11_meta_new (PyTypeObject *metaclass, PyObject *args,
93+ PyObject *kwargs) {
94+ PyObject *bases = PyTuple_GetItem (args, 1 ); // arguments: (name, bases, dict)
95+ if (!bases)
96+ return nullptr ;
97+
98+ auto &internals = get_internals ();
99+ auto num_cpp_bases = 0 ;
100+ for (auto base : reinterpret_borrow<tuple>(bases)) {
101+ auto base_type = (PyTypeObject *) base.ptr ();
102+ auto instance_size = static_cast <size_t >(base_type->tp_basicsize );
103+ if (PyObject_IsSubclass (base.ptr (), internals.get_base (instance_size)))
104+ ++num_cpp_bases;
105+ }
106+
107+ if (num_cpp_bases > 1 ) {
108+ PyErr_SetString (PyExc_TypeError, " Can't inherit from multiple C++ classes in Python."
109+ " Use py::class_ to define the class in C++ instead." );
110+ return nullptr ;
111+ } else {
112+ return PyType_Type.tp_new (metaclass, args, kwargs);
113+ }
114+ }
115+
88116/* * Types with static properties need to handle `Type.static_prop = x` in a specific way.
89117 By default, Python replaces the `static_property` itself, but for wrapped C++ types
90118 we need to call `static_property.__set__()` in order to propagate the new value to
@@ -135,6 +163,8 @@ inline PyTypeObject* make_default_metaclass() {
135163 type->tp_name = name;
136164 type->tp_base = &PyType_Type;
137165 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
166+
167+ type->tp_new = pybind11_meta_new;
138168 type->tp_setattro = pybind11_meta_setattro;
139169
140170 if (PyType_Ready (type) < 0 )
@@ -145,7 +175,7 @@ inline PyTypeObject* make_default_metaclass() {
145175
146176// / Instance creation function for all pybind11 types. It only allocates space for the
147177// / C++ object, but doesn't call the constructor -- an `__init__` function must do that.
148- extern " C" inline PyObject *pybind11_new (PyTypeObject *type, PyObject *, PyObject *) {
178+ extern " C" inline PyObject *pybind11_object_new (PyTypeObject *type, PyObject *, PyObject *) {
149179 PyObject *self = type->tp_alloc (type, 0 );
150180 auto instance = (instance_essentials<void > *) self;
151181 auto tinfo = get_type_info (type);
@@ -159,7 +189,7 @@ extern "C" inline PyObject *pybind11_new(PyTypeObject *type, PyObject *, PyObjec
159189// / An `__init__` function constructs the C++ object. Users should provide at least one
160190// / of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the
161191// / following default function will be used which simply throws an exception.
162- extern " C" inline int pybind11_init (PyObject *self, PyObject *, PyObject *) {
192+ extern " C" inline int pybind11_object_init (PyObject *self, PyObject *, PyObject *) {
163193 PyTypeObject *type = Py_TYPE (self);
164194 std::string msg;
165195#if defined(PYPY_VERSION)
@@ -173,7 +203,7 @@ extern "C" inline int pybind11_init(PyObject *self, PyObject *, PyObject *) {
173203
174204// / Instance destructor function for all pybind11 types. It calls `type_info.dealloc`
175205// / to destroy the C++ object itself, while the rest is Python bookkeeping.
176- extern " C" inline void pybind11_dealloc (PyObject *self) {
206+ extern " C" inline void pybind11_object_dealloc (PyObject *self) {
177207 auto instance = (instance_essentials<void > *) self;
178208 if (instance->value ) {
179209 auto type = Py_TYPE (self);
@@ -190,7 +220,7 @@ extern "C" inline void pybind11_dealloc(PyObject *self) {
190220 }
191221 }
192222 if (!found)
193- pybind11_fail (" pybind11_dealloc (): Tried to deallocate unregistered instance!" );
223+ pybind11_fail (" pybind11_object_dealloc (): Tried to deallocate unregistered instance!" );
194224
195225 if (instance->weakrefs )
196226 PyObject_ClearWeakRefs (self);
@@ -230,9 +260,9 @@ inline PyObject *make_object_base_type(size_t instance_size) {
230260 type->tp_basicsize = static_cast <ssize_t >(instance_size);
231261 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
232262
233- type->tp_new = pybind11_new ;
234- type->tp_init = pybind11_init ;
235- type->tp_dealloc = pybind11_dealloc ;
263+ type->tp_new = pybind11_object_new ;
264+ type->tp_init = pybind11_object_init ;
265+ type->tp_dealloc = pybind11_object_dealloc ;
236266
237267 /* Support weak references (needed for the keep_alive feature) */
238268 type->tp_weaklistoffset = offsetof (instance_essentials<void >, weakrefs);
@@ -429,7 +459,7 @@ inline PyObject* make_new_python_type(const type_record &rec) {
429459 type->tp_bases = bases.release ().ptr ();
430460
431461 /* Don't inherit base __init__ */
432- type->tp_init = pybind11_init ;
462+ type->tp_init = pybind11_object_init ;
433463
434464 /* Supported protocols */
435465 type->tp_as_number = &heap_type->as_number ;
0 commit comments