[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 */