[pypy-issue] Issue #2480: cpyext tp_bases doesn't properly expose multiple inheritance (pypy/pypy)
Jason Rhinelander
issues-reply at bitbucket.org
Thu Feb 23 11:54:08 EST 2017
New issue 2480: cpyext tp_bases doesn't properly expose multiple inheritance
https://bitbucket.org/pypy/pypy/issues/2480/cpyext-tp_bases-doesnt-properly-expose
Jason Rhinelander:
I'm working to extend pybind11's multiple inheritance support to allow multiple inheritance from the Python side (https://github.com/pybind/pybind11/pull/693), and ran into an issue where PyPy's `PyTypeObject.tp_bases` only contains the first parent class, e.g.:
```
class B1(object):
pass
class B2(object):
pass
class A(B1, B2):
pass
```
cpyext code that gets the `PyTypeObject *` for `A` will have `tp_bases` set to a tuple of just `B1` instead of both `B1` and `B2`.
`A.__bases__`, however, contains the correct types.
My test code for this in this commit: https://github.com/jagerman/pybind11/commit/7e13ad2d044de7fd8641bac07ab70871c130421a
combined with this test code:
```
from __future__ import print_function
from pybind11_tests import Base1, Base2, debug_tp_bases
class A(object):
pass
class A2(object):
pass
class A3(A, A2):
pass
class B(Base1, Base2):
def __init__(self):
Base1.__init__(self, 1)
Base2.__init__(self, 2)
class C(A, B):
def __init__(self):
B.__init__(self)
print("A.__bases__:", A.__bases__)
debug_tp_bases(A)
print("A3.__bases__:", A3.__bases__)
debug_tp_bases(A3)
print("B.__bases__:", B.__bases__)
debug_tp_bases(B)
print("C.__bases__:", C.__bases__)
debug_tp_bases(C)
```
gives me (using current pypy nightly):
```
A.__bases__: (<type 'object'>,)
Type `A' tp_bases:
- object
A3.__bases__: (<class '__main__.A'>, <class '__main__.A2'>)
Type `A3' tp_bases:
- A
B.__bases__: (<class 'pybind11_tests.Base1'>, <class 'pybind11_tests.Base2'>)
Type `B' tp_bases:
- Base1
C.__bases__: (<class '__main__.A'>, <class '__main__.B'>)
Type `C' tp_bases:
- A
```
whereas CPython 2 and 3 give:
```
A.__bases__: (<type 'object'>,)
Type `A' tp_bases:
- object
A3.__bases__: (<class '__main__.A'>, <class '__main__.A2'>)
Type `A3' tp_bases:
- A
- A2
B.__bases__: (<class 'pybind11_tests.Base1'>, <class 'pybind11_tests.Base2'>)
Type `B' tp_bases:
- pybind11_tests.Base1
- pybind11_tests.Base2
C.__bases__: (<class '__main__.A'>, <class '__main__.B'>)
Type `C' tp_bases:
- A
- B
```
More information about the pypy-issue
mailing list