[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.32,2.16.8.33
Guido van Rossum
gvanrossum@users.sourceforge.net
Wed, 06 Jun 2001 08:40:40 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv9395
Modified Files:
Tag: descr-branch
typeobject.c
Log Message:
- Correct __bases__ calculation: take multiple bases into account, and
make sure every type (except PyBaseObject_Type) is a subtype of
PyBaseObject_Type.
- New slots for type objects: __basicsize__, __itemsize__, __flags__,
__weaklistoffset__, __dictoffset__.
- Initialize a type's __dict__ when it's asked for.
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.32
retrieving revision 2.16.8.33
diff -C2 -r2.16.8.32 -r2.16.8.33
*** typeobject.c 2001/06/06 14:27:54 2.16.8.32
--- typeobject.c 2001/06/06 15:40:38 2.16.8.33
***************
*** 9,13 ****
--- 9,20 ----
struct memberlist type_members[] = {
{"__name__", T_STRING, offsetof(PyTypeObject, tp_name), READONLY},
+ {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
+ {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
+ {"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
{"__doc__", T_STRING, offsetof(PyTypeObject, tp_doc), READONLY},
+ {"__weaklistoffset__", T_LONG,
+ offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
+ {"__dictoffset__", T_LONG,
+ offsetof(PyTypeObject, tp_dictoffset), READONLY},
{0}
};
***************
*** 16,23 ****
type_bases(PyTypeObject *type, void *context)
{
! if (type->tp_base == NULL)
! return PyTuple_New(0);
! else
! return Py_BuildValue("(O)", type->tp_base);
}
--- 23,41 ----
type_bases(PyTypeObject *type, void *context)
{
! PyObject *bases;
! PyTypeObject *base;
!
! bases = type->tp_bases;
! if (bases != NULL) {
! Py_INCREF(bases);
! return bases;
! }
! base = type->tp_base;
! if (base == NULL) {
! if (type == &PyBaseObject_Type)
! return PyTuple_New(0);
! base = &PyBaseObject_Type;
! }
! return Py_BuildValue("(O)", base);
}
***************
*** 32,37 ****
{
if (type->tp_dict == NULL) {
! Py_INCREF(Py_None);
! return Py_None;
}
return PyDictProxy_New(type->tp_dict);
--- 50,59 ----
{
if (type->tp_dict == NULL) {
! if (PyType_InitDict(type) < 0)
! return NULL;
! if (type->tp_dict == NULL) {
! Py_INCREF(Py_None);
! return Py_None;
! }
}
return PyDictProxy_New(type->tp_dict);
***************
*** 154,157 ****
--- 176,183 ----
issubtype(PyTypeObject *a, PyTypeObject *b)
{
+ PyObject *bases;
+ PyTypeObject *base;
+ int i, n;
+
if (b == &PyBaseObject_Type)
return 1; /* Every type is an implicit subtype of this */
***************
*** 159,163 ****
--- 185,203 ----
if (a == b)
return 1;
+ bases = a->tp_bases;
a = a->tp_base;
+ if (bases != NULL && PyTuple_Check(bases)) {
+ n = PyTuple_GET_SIZE(bases);
+ for (i = 0; i < n; i++) {
+ base = (PyTypeObject *)
+ PyTuple_GET_ITEM(bases, i);
+ if (base == b)
+ return 1;
+ if (base != a) {
+ if (issubtype(base, b))
+ return 1;
+ }
+ }
+ }
}
return 0;
***************
*** 272,278 ****
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
! /* Copy slots and dict from the base type */
Py_INCREF(base);
type->tp_base = base;
if (PyType_InitDict(type) < 0) {
Py_DECREF(type);
--- 312,325 ----
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
! /* Set tp_base and tp_bases properly */
! if (PyTuple_GET_SIZE(bases) == 0)
! bases = Py_BuildValue("(O)", &PyBaseObject_Type);
! else
! Py_INCREF(bases);
! type->tp_bases = bases;
Py_INCREF(base);
type->tp_base = base;
+
+ /* Copy slots and dict from the base type */
if (PyType_InitDict(type) < 0) {
Py_DECREF(type);
***************
*** 346,350 ****
int b_size = base->tp_basicsize;
- /* XXX what about tp_itemsize? */
assert((type->tp_flags & Py_TPFLAGS_GC) >=
(base->tp_flags & Py_TPFLAGS_GC)); /* base has GC, type not! */
--- 393,396 ----
***************
*** 354,357 ****
--- 400,408 ----
b_size -= PyGC_HEAD_SIZE;
assert(t_size >= b_size); /* type smaller than base! */
+ if (type->tp_itemsize || base->tp_itemsize) {
+ /* If itemsize is involved, stricter rules */
+ return t_size != b_size ||
+ type->tp_itemsize != base->tp_itemsize;
+ }
if (t_size == b_size)
return 0;
***************
*** 384,387 ****
--- 435,446 ----
static char *kwlist[] = {"name", "bases", "dict", 0};
+ if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+ (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) {
+ /* type(x) -> x.__class__ */
+ PyObject *x = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(x->ob_type);
+ return (PyObject *) x->ob_type;
+ }
+
/* Check arguments (again?!?! yes, alas -- we need the bases!) */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
***************
*** 429,436 ****
PyTypeObject PyType_Type = {
PyObject_HEAD_INIT(&PyType_Type)
! 0, /* Number of items for varobject */
! "type", /* Name of this type */
! sizeof(etype) + sizeof(struct memberlist), /* Basic object size */
! 0, /* Item size for varobject */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
--- 488,495 ----
PyTypeObject PyType_Type = {
PyObject_HEAD_INIT(&PyType_Type)
! 0, /* ob_size */
! "type", /* tp_name */
! sizeof(etype) + sizeof(struct memberlist), /* tp_basicsize */
! 0, /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
***************
*** 445,449 ****
(ternaryfunc)type_call, /* tp_call */
0, /* tp_str */
! PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
--- 504,508 ----
(ternaryfunc)type_call, /* tp_call */
0, /* tp_str */
! PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
***************
*** 496,500 ****
0, /* tp_call */
0, /* tp_str */
! PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
--- 555,559 ----
0, /* tp_call */
0, /* tp_str */
! PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */