cpyext: tp_new not called in some multiple inheritance situations
Created originally on Bitbucket by jagerman (Jason Rhinelander)
I've been testing out the pypy2-5.9.0 release with pybind11 and run into a segfault with one of the multiple inheritance tests (which was fine under 5.8.0 and under CPython). Basically the test amounts to:
class PyBase(object): pass class MI1b(PyBase, Base1): # Doesn't work def __init__(self): PyBase.__init__(self) Base1.__init__(self) class MI1c(Base1, PyBase): # Works def __init__(self): PyBase.__init__(self) Base1.__init__(self)
Base1 is a C extension class which inherits from a common C extension base class (
pybind11_object, which itself inherits from
object) with a
tp_new that initializes extra data needed for pybind objects. That base class
tp_new, however, never gets called in the
MI1b case, and so the instance doesn't get initialized properly, leading to a segfault when trying to access the expected internal data.
mro() of the two classes are:
# Working class (MI1c) MRO: [<class 'test_multiple_inheritance.MI1c'>, <class 'pybind11_tests.multiple_inheritance.Base1'>, <class 'pybind11_object'>, <class 'test_multiple_inheritance.PyBase'>, <type 'object'>] # Non-working class (MI1b) MRO: [<class 'test_multiple_inheritance.MI1b'>, <class 'test_multiple_inheritance.PyBase'>, <class 'pybind11_tests.multiple_inheritance.Base1'>, <class 'pybind11_object'>, <type 'object'>]
pybind11_object is the type with the custom
(Though I think that extra
pybind11_object base class doesn't really matter to the issue:
tp_new isn't called even if I set it directly on the
Base1 type object).
I suspect that the fix for #2666 (closed) is involved here: I tried a few pypy nightlies, and the problem doesn't occur in the builds up to and including
pypy-c-jit-92494-8e1aad229f8e-linux64.tar.bz2, but does starting with
pypy-c-jit-92504-5acb984186b5-linux64.tar.bz2--which looks to coincide with the timing of the #2666 (closed) fix (3f4fc7771154).