[pypy-issue] Issue #2445: Support pybind11 in conjunction with PyPy's cpyext: Multiple inheritance broken (?) (pypy/pypy)

Wenzel Jakob issues-reply at bitbucket.org
Sat Dec 3 19:05:14 EST 2016


New issue 2445: Support pybind11 in conjunction with PyPy's cpyext: Multiple inheritance broken (?)
https://bitbucket.org/pypy/pypy/issues/2445/support-pybind11-in-conjunction-with-pypys

Wenzel Jakob:

Hi,

one of the last major stumbling blocks in getting pybind11 to work nicely in conjunction with PyPy is multiple inheritance. It seems that PyPy is quite a bit more restrictive in terms of how bases can occur in a type declaration.

Instructions to reproduce:
```
#!bash

$ git clone -b pypy-mi https://github.com/wjakob/pybind11
$ cd pybind11
$ pypy-c -m pip install pytest # Needed or cmake will complain
$ cmake -DPYTHON_EXECUTABLE:FILEPATH=<path-to-pypy-c> .
$ make -j 4
$ cd tests
$ pypy-c
Python 2.7.12 (98f8c7e783db, Nov 23 2016, 15:31:26)
[PyPy 5.7.0-alpha0 with GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``it was few yaks too late''
>>>> import pybind11_tests
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: Base12: PyType_Ready failed (TypeError: instance layout conflicts in multiple inheritance)!
```

The following (abbreviated) code in the pybind11 test suite (``tests/test_multiple_inheritance.cpp``) is to blame:
```cpp
/// Declare a new-style class Base1 deriving from object
py::class_<Base1>(m, "Base1");

/// Declare a new-style class Base2 deriving from object
py::class_<Base2>(m, "Base2");

/// Declare a new-style class Base12 deriving form Base1 and Base2
py::class_<Base12, Base1, Base2>(m, "Base12"); # Kaboom (instance layout conflicts in multiple inheritance)
```

What this code does is to allocate and set up a heap type data structure and call ``PyType_Ready`` three times in a row. In the third declaration, the ``PyObject*`` associated with the ``Base1`` and ``Base2`` types are provided as a tuple in the ``ht_type.tp_bases`` field. All of this works without problems in Python 2/3. The instance layout is also as simple as it gets. They are the same and basically just contain a pointer to the C++ instance being wrapped.

(Hence, I suspect a cpyext bug or limitation that should probably be addressed.)




More information about the pypy-issue mailing list