Commit bd252e34 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Copy tp_as_number *after* commonClassSetup

This is important because commonClassSetup will modify tp_as_number
if it exists.  This causes an issue when an extension class uses
multiple inheritance; it will inherit the tp_as_number from its
main base, but then copy in any fields from its secondary bases. But
tp_as_number points to the same struct as its parent, so it would
update the parent's slots accidentally.

So, move the tp_as_number copying to where CPython does it, or at least,
after the calls to inherit_slots.
parent 72cd01ef
...@@ -3300,19 +3300,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept { ...@@ -3300,19 +3300,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
assert(cls->tp_name); assert(cls->tp_name);
// Inherit some special protocols. Normally methods are automatically inherited,
// when a Python class is declared, but that may not be the case with C extensions.
if (base != NULL) {
if (cls->tp_as_number == NULL)
cls->tp_as_number = base->tp_as_number;
if (cls->tp_as_sequence == NULL)
cls->tp_as_sequence = base->tp_as_sequence;
if (cls->tp_as_mapping == NULL)
cls->tp_as_mapping = base->tp_as_mapping;
if (cls->tp_as_buffer == NULL)
cls->tp_as_buffer = base->tp_as_buffer;
}
if (cls->tp_call) { if (cls->tp_call) {
cls->tpp_call.capi_val = tppProxyToTpCall<CAPI>; cls->tpp_call.capi_val = tppProxyToTpCall<CAPI>;
cls->tpp_call.cxx_val = tppProxyToTpCall<CXX>; cls->tpp_call.cxx_val = tppProxyToTpCall<CXX>;
...@@ -3355,6 +3342,19 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept { ...@@ -3355,6 +3342,19 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
} }
} }
// Inherit some special protocols. Normally methods are automatically inherited,
// when a Python class is declared, but that may not be the case with C extensions.
if (base != NULL) {
if (cls->tp_as_number == NULL)
cls->tp_as_number = base->tp_as_number;
if (cls->tp_as_sequence == NULL)
cls->tp_as_sequence = base->tp_as_sequence;
if (cls->tp_as_mapping == NULL)
cls->tp_as_mapping = base->tp_as_mapping;
if (cls->tp_as_buffer == NULL)
cls->tp_as_buffer = base->tp_as_buffer;
}
if (cls->tp_alloc == &PystonType_GenericAlloc) if (cls->tp_alloc == &PystonType_GenericAlloc)
cls->tp_alloc = &PyType_GenericAlloc; cls->tp_alloc = &PyType_GenericAlloc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment