# HG changeset patch # User Martin Teichmann # Date 1391851158 -3600 # Sat Feb 08 10:19:18 2014 +0100 # Node ID 41c2fb4e12853db2ea9ab29561d47b8437dc24cc # Parent b541ecd321150049a4372df790de8a6d9a5b583d fix technical bug in PyType_Ready mro_internal uses solid_base, which expects the type it is supposted to work on to already have weaklistoffset, dictoffset and itemsize initialized. This patch puts this initialization before mro_internal. By coincidence, nothing bad happens even without this patch, but for future changes the order should be right. diff -r b541ecd32115 -r 41c2fb4e1285 Objects/typeobject.c --- a/Objects/typeobject.c Fri Feb 07 16:11:17 2014 -0800 +++ b/Objects/typeobject.c Sat Feb 08 10:19:18 2014 +0100 @@ -4627,15 +4627,15 @@ goto error; } + /* Inherit special flags from dominant base */ + if (type->tp_base != NULL) + inherit_special(type, type->tp_base); + /* Calculate method resolution order */ if (mro_internal(type) < 0) { goto error; } - /* Inherit special flags from dominant base */ - if (type->tp_base != NULL) - inherit_special(type, type->tp_base); - /* Initialize tp_dict properly */ bases = type->tp_mro; assert(bases != NULL); # HG changeset patch # User Martin Teichmann # Date 1391851428 -3600 # Sat Feb 08 10:23:48 2014 +0100 # Node ID b867375a4810b578194570f08d2bcd72defe0482 # Parent 41c2fb4e12853db2ea9ab29561d47b8437dc24cc add new flag Py_TPFLAGS_SOLID flag classes that add something to their data structure. This patch will allow new modules written in C to show to python that their internal structure is different from their base's, even if its size did not change. diff -r 41c2fb4e1285 -r b867375a4810 Include/object.h --- a/Include/object.h Sat Feb 08 10:19:18 2014 +0100 +++ b/Include/object.h Sat Feb 08 10:23:48 2014 +0100 @@ -651,6 +651,9 @@ /* Type structure has tp_finalize member (3.4) */ #define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) +/* the memory layout is incompatible to the type's bases */ +#define Py_TPFLAGS_SOLID (1UL << 1) + #ifdef Py_LIMITED_API #define PyType_HasFeature(t,f) ((PyType_GetFlags(t) & (f)) != 0) #else diff -r 41c2fb4e1285 -r b867375a4810 Objects/typeobject.c --- a/Objects/typeobject.c Sat Feb 08 10:19:18 2014 +0100 +++ b/Objects/typeobject.c Sat Feb 08 10:23:48 2014 +0100 @@ -1840,13 +1840,16 @@ { PyTypeObject *base; + if (type->tp_flags & Py_TPFLAGS_SOLID) + return type; if (type->tp_base) base = solid_base(type->tp_base); else base = &PyBaseObject_Type; - if (extra_ivars(type, base)) + if (extra_ivars(type, base)) { + type->tp_flags |= Py_TPFLAGS_SOLID; return type; - else + } else return base; } # HG changeset patch # User Martin Teichmann # Date 1391851450 -3600 # Sat Feb 08 10:24:10 2014 +0100 # Node ID 1dd363681f50010f4cc1b03ad9693277415f7367 # Parent b867375a4810b578194570f08d2bcd72defe0482 cosmetic change just make code look a bit nicer. diff -r b867375a4810 -r 1dd363681f50 Objects/typeobject.c --- a/Objects/typeobject.c Sat Feb 08 10:23:48 2014 +0100 +++ b/Objects/typeobject.c Sat Feb 08 10:24:10 2014 +0100 @@ -4334,8 +4334,6 @@ type->tp_new = base->tp_new; } } - if (type->tp_basicsize == 0) - type->tp_basicsize = base->tp_basicsize; /* Copy other non-function slots */ @@ -4343,6 +4341,7 @@ #define COPYVAL(SLOT) \ if (type->SLOT == 0) type->SLOT = base->SLOT + COPYVAL(tp_basicsize); COPYVAL(tp_itemsize); COPYVAL(tp_weaklistoffset); COPYVAL(tp_dictoffset);