[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.28,2.29
Guido van Rossum
gvanrossum@users.sourceforge.net
Fri, 10 Aug 2001 14:24:10 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv12100
Modified Files:
typeobject.c
Log Message:
- Big changes to fix SF bug #442833 (a nasty multiple inheritance
problem). inherit_slots() is split in two parts: inherit_special()
which inherits the flags and a few very special members from the
dominant base; inherit_slots() which inherits only regular slots,
and is now called for each base in the MRO in turn. These are now
both void functions since they don't have error returns.
- Added object.__setitem__() back -- for the same reason as
object.__new__(): a subclass of object should be able to call
object.__new__().
- add_wrappers() was moved around to be closer to where it is used (it
was defined together with add_methods() etc., but has nothing to do
with these).
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.28
retrieving revision 2.29
diff -C2 -d -r2.28 -r2.29
*** typeobject.c 2001/08/10 17:39:49 2.28
--- typeobject.c 2001/08/10 21:24:08 2.29
***************
*** 5,10 ****
#include "structmember.h"
- staticforward int add_members(PyTypeObject *, struct memberlist *);
-
static struct memberlist type_members[] = {
{"__name__", T_STRING, offsetof(PyTypeObject, tp_name), READONLY},
--- 5,8 ----
***************
*** 648,652 ****
}
type->tp_basicsize = slotoffset;
! add_members(type, et->members);
/* Special case some slots */
--- 646,650 ----
}
type->tp_basicsize = slotoffset;
! type->tp_members = et->members;
/* Special case some slots */
***************
*** 883,887 ****
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
! 0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
--- 881,885 ----
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
! PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
***************
*** 930,952 ****
static int
- add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped)
- {
- PyObject *dict = type->tp_defined;
-
- for (; wraps->name != NULL; wraps++) {
- PyObject *descr;
- if (PyDict_GetItemString(dict, wraps->name))
- continue;
- descr = PyDescr_NewWrapper(type, wraps, wrapped);
- if (descr == NULL)
- return -1;
- if (PyDict_SetItemString(dict, wraps->name, descr) < 0)
- return -1;
- Py_DECREF(descr);
- }
- return 0;
- }
-
- static int
add_members(PyTypeObject *type, struct memberlist *memb)
{
--- 928,931 ----
***************
*** 987,1003 ****
}
! staticforward int add_operators(PyTypeObject *);
! static int
inherit_slots(PyTypeObject *type, PyTypeObject *base)
{
! int oldsize, newsize;
#undef COPYSLOT
#undef COPYNUM
#undef COPYSEQ
#undef COPYMAP
#define COPYSLOT(SLOT) \
! if (!type->SLOT) type->SLOT = base->SLOT
#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT)
--- 966,1041 ----
}
! static void
! inherit_special(PyTypeObject *type, PyTypeObject *base)
! {
! int oldsize, newsize;
! /* Special flag magic */
! if (!type->tp_as_buffer && base->tp_as_buffer) {
! type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER;
! type->tp_flags |=
! base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER;
! }
! if (!type->tp_as_sequence && base->tp_as_sequence) {
! type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
! type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
! }
! if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
! (base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
! if ((!type->tp_as_number && base->tp_as_number) ||
! (!type->tp_as_sequence && base->tp_as_sequence)) {
! type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
! if (!type->tp_as_number && !type->tp_as_sequence) {
! type->tp_flags |= base->tp_flags &
! Py_TPFLAGS_HAVE_INPLACEOPS;
! }
! }
! /* Wow */
! }
! if (!type->tp_as_number && base->tp_as_number) {
! type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
! type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
! }
!
! /* Copying basicsize is connected to the GC flags */
! oldsize = PyType_BASICSIZE(base);
! newsize = type->tp_basicsize ? PyType_BASICSIZE(type) : oldsize;
! if (!(type->tp_flags & Py_TPFLAGS_GC) &&
! (base->tp_flags & Py_TPFLAGS_GC) &&
! (type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
! (!type->tp_traverse && !type->tp_clear)) {
! type->tp_flags |= Py_TPFLAGS_GC;
! if (type->tp_traverse == NULL)
! type->tp_traverse = base->tp_traverse;
! if (type->tp_clear == NULL)
! type->tp_clear = base->tp_clear;
! }
! if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
! if (base != &PyBaseObject_Type ||
! (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
! if (type->tp_new == NULL)
! type->tp_new = base->tp_new;
! }
! }
! PyType_SET_BASICSIZE(type, newsize);
! }
!
! static void
inherit_slots(PyTypeObject *type, PyTypeObject *base)
{
! PyTypeObject *basebase;
+ #undef SLOTDEFINED
#undef COPYSLOT
#undef COPYNUM
#undef COPYSEQ
#undef COPYMAP
+
+ #define SLOTDEFINED(SLOT) \
+ (base->SLOT != 0 && \
+ (basebase == NULL || base->SLOT != basebase->SLOT))
+
#define COPYSLOT(SLOT) \
! if (!type->SLOT && SLOTDEFINED(SLOT)) type->SLOT = base->SLOT
#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT)
***************
*** 1005,1011 ****
#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT)
! if (type->tp_as_number == NULL)
! type->tp_as_number = base->tp_as_number;
! else if (base->tp_as_number) {
COPYNUM(nb_add);
COPYNUM(nb_subtract);
--- 1043,1053 ----
#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT)
! /* This won't inherit indirect slots (from tp_as_number etc.)
! if type doesn't provide the space. */
!
! if (type->tp_as_number != NULL && base->tp_as_number != NULL) {
! basebase = base->tp_base;
! if (basebase->tp_as_number == NULL)
! basebase = NULL;
COPYNUM(nb_add);
COPYNUM(nb_subtract);
***************
*** 1050,1056 ****
}
! if (type->tp_as_sequence == NULL)
! type->tp_as_sequence = base->tp_as_sequence;
! else if (base->tp_as_sequence) {
COPYSEQ(sq_length);
COPYSEQ(sq_concat);
--- 1092,1099 ----
}
! if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
! basebase = base->tp_base;
! if (basebase->tp_as_sequence == NULL)
! basebase = NULL;
COPYSEQ(sq_length);
COPYSEQ(sq_concat);
***************
*** 1065,1071 ****
}
! if (type->tp_as_mapping == NULL)
! type->tp_as_mapping = base->tp_as_mapping;
! else if (base->tp_as_mapping) {
COPYMAP(mp_length);
COPYMAP(mp_subscript);
--- 1108,1115 ----
}
! if (type->tp_as_mapping != NULL && base->tp_as_mapping != NULL) {
! basebase = base->tp_base;
! if (basebase->tp_as_mapping == NULL)
! basebase = NULL;
COPYMAP(mp_length);
COPYMAP(mp_subscript);
***************
*** 1073,1115 ****
}
! /* Special flag magic */
! if (!type->tp_as_buffer && base->tp_as_buffer) {
! type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER;
! type->tp_flags |=
! base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER;
! }
! if (!type->tp_as_sequence && base->tp_as_sequence) {
! type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
! type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
! }
! if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
! (base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
! if ((!type->tp_as_number && base->tp_as_number) ||
! (!type->tp_as_sequence && base->tp_as_sequence)) {
! type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
! if (!type->tp_as_number && !type->tp_as_sequence) {
! type->tp_flags |= base->tp_flags &
! Py_TPFLAGS_HAVE_INPLACEOPS;
! }
! }
! /* Wow */
! }
! if (!type->tp_as_number && base->tp_as_number) {
! type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
! type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
! }
!
! /* Copying basicsize is connected to the GC flags */
! oldsize = PyType_BASICSIZE(base);
! newsize = type->tp_basicsize ? PyType_BASICSIZE(type) : oldsize;
! if (!(type->tp_flags & Py_TPFLAGS_GC) &&
! (base->tp_flags & Py_TPFLAGS_GC) &&
! (type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
! (!type->tp_traverse && !type->tp_clear)) {
! type->tp_flags |= Py_TPFLAGS_GC;
! COPYSLOT(tp_traverse);
! COPYSLOT(tp_clear);
! }
! PyType_SET_BASICSIZE(type, newsize);
COPYSLOT(tp_itemsize);
--- 1117,1121 ----
}
! basebase = base->tp_base;
COPYSLOT(tp_itemsize);
***************
*** 1153,1166 ****
COPYSLOT(tp_init);
COPYSLOT(tp_alloc);
- if (base != &PyBaseObject_Type ||
- (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
- COPYSLOT(tp_new);
- }
COPYSLOT(tp_free);
}
-
- return 0;
}
int
PyType_Ready(PyTypeObject *type)
--- 1159,1168 ----
COPYSLOT(tp_init);
COPYSLOT(tp_alloc);
COPYSLOT(tp_free);
}
}
+ staticforward int add_operators(PyTypeObject *);
+
int
PyType_Ready(PyTypeObject *type)
***************
*** 1238,1249 ****
}
/* Initialize tp_dict properly */
if (!PyType_HasFeature(type, Py_TPFLAGS_DYNAMICTYPE)) {
/* For a static type, tp_dict is the consolidation
! of the tp_defined of its bases in MRO. Earlier
! bases override later bases; since d.update() works
! the other way, we walk the MRO sequence backwards. */
Py_DECREF(type->tp_dict);
! type->tp_dict = PyDict_New();
if (type->tp_dict == NULL)
goto error;
--- 1240,1253 ----
}
+ /* Inherit special flags from dominant base */
+ if (type->tp_base != NULL)
+ inherit_special(type, type->tp_base);
+
/* Initialize tp_dict properly */
if (!PyType_HasFeature(type, Py_TPFLAGS_DYNAMICTYPE)) {
/* For a static type, tp_dict is the consolidation
! of the tp_defined of its bases in MRO. */
Py_DECREF(type->tp_dict);
! type->tp_dict = PyDict_Copy(type->tp_defined);
if (type->tp_dict == NULL)
goto error;
***************
*** 1252,1269 ****
assert(PyTuple_Check(bases));
n = PyTuple_GET_SIZE(bases);
! for (i = n; --i >= 0; ) {
base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i);
assert(PyType_Check(base));
x = base->tp_defined;
! if (x != NULL && PyDict_Update(type->tp_dict, x) < 0)
goto error;
}
}
! /* Inherit slots from direct base */
! if (type->tp_base != NULL)
! if (inherit_slots(type, type->tp_base) < 0)
! goto error;
assert(type->tp_dict != NULL);
type->tp_flags =
--- 1256,1281 ----
assert(PyTuple_Check(bases));
n = PyTuple_GET_SIZE(bases);
! for (i = 1; i < n; i++) {
base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i);
assert(PyType_Check(base));
x = base->tp_defined;
! if (x != NULL && PyDict_Merge(type->tp_dict, x, 0) < 0)
goto error;
+ inherit_slots(type, base);
}
}
! /* Some more special stuff */
! base = type->tp_base;
! if (base != NULL) {
! if (type->tp_as_number == NULL)
! type->tp_as_number = base->tp_as_number;
! if (type->tp_as_sequence == NULL)
! type->tp_as_sequence = base->tp_as_sequence;
! if (type->tp_as_mapping == NULL)
! type->tp_as_mapping = base->tp_as_mapping;
! }
+ /* All done -- set the ready flag */
assert(type->tp_dict != NULL);
type->tp_flags =
***************
*** 1910,1913 ****
--- 1922,1944 ----
return -1;
return PyDict_SetItemString(type->tp_defined, "__new__", func);
+ }
+
+ static int
+ add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped)
+ {
+ PyObject *dict = type->tp_defined;
+
+ for (; wraps->name != NULL; wraps++) {
+ PyObject *descr;
+ if (PyDict_GetItemString(dict, wraps->name))
+ continue;
+ descr = PyDescr_NewWrapper(type, wraps, wrapped);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict, wraps->name, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ return 0;
}