[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.27,2.16.8.28

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 05 Jun 2001 08:30:41 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv798

Modified Files:
      Tag: descr-branch
	typeobject.c 
Log Message:
Allow creating subtypes without a base type (specifying an explicit
__metaclass__).  In this case, the base defaults to "object", whose C
name has to be PyBaseObject_Type because PyObject_Type is an existing
function.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.27
retrieving revision 2.16.8.28
diff -C2 -r2.16.8.27 -r2.16.8.28
*** typeobject.c	2001/06/05 11:41:23	2.16.8.27
--- typeobject.c	2001/06/05 15:30:39	2.16.8.28
***************
*** 58,62 ****
  	if (type->tp_new == NULL) {
  		PyErr_Format(PyExc_TypeError,
! 			     "cannot construct '%.100s' instances",
  			     type->tp_name);
  		return NULL;
--- 58,62 ----
  	if (type->tp_new == NULL) {
  		PyErr_Format(PyExc_TypeError,
! 			     "cannot create '%.100s' instances",
  			     type->tp_name);
  		return NULL;
***************
*** 99,103 ****
  	if (self == NULL)
  		return NULL;
! 	if (type->tp_init(self, args, kwds) < 0) {
  		Py_DECREF(self);
  		return NULL;
--- 99,103 ----
  	if (self == NULL)
  		return NULL;
! 	if (type->tp_init != NULL && type->tp_init(self, args, kwds) < 0) {
  		Py_DECREF(self);
  		return NULL;
***************
*** 112,124 ****
  {
  	int dictoffset = self->ob_type->tp_dictoffset;
! 	PyTypeObject *base;
  	destructor f;
  
  	/* This exists so we can DECREF self->ob_type */
  
! 	base = self->ob_type->tp_base;
! 	while ((f = base->tp_dealloc) == subtype_dealloc)
  		base = base->tp_base;
! 	if (dictoffset && !base->tp_dictoffset) {
  		PyObject **dictptr = (PyObject **) ((char *)self + dictoffset);
  		PyObject *dict = *dictptr;
--- 112,125 ----
  {
  	int dictoffset = self->ob_type->tp_dictoffset;
! 	PyTypeObject *type, *base;
  	destructor f;
  
  	/* This exists so we can DECREF self->ob_type */
  
! 	type = self->ob_type;
! 	base = type->tp_base;
! 	while (base && (f = base->tp_dealloc) == subtype_dealloc)
  		base = base->tp_base;
! 	if (dictoffset && (base == NULL || !base->tp_dictoffset)) {
  		PyObject **dictptr = (PyObject **) ((char *)self + dictoffset);
  		PyObject *dict = *dictptr;
***************
*** 129,134 ****
  	}
  	f(self);
! 	if (self->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
! 		Py_DECREF(self->ob_type);
  	}
  }
--- 130,136 ----
  	}
  	f(self);
! 	/* Can't reference self beyond this point */
! 	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
! 		Py_DECREF(type);
  	}
  }
***************
*** 146,150 ****
  } etype;
  
! /* TypeType's constructor is called when a type is subclassed */
  static int
  type_init(PyObject *self, PyObject *args, PyObject *kwds)
--- 148,152 ----
  } etype;
  
! /* TypeType's initializer; called when a type is subclassed */
  static int
  type_init(PyObject *self, PyObject *args, PyObject *kwds)
***************
*** 152,156 ****
  	PyObject *name, *bases, *dict, *x, *slots;
  	PyTypeObject *type, *base;
! 	char *dummy = NULL;
  	etype *et;
  	struct memberlist *mp;
--- 154,158 ----
  	PyObject *name, *bases, *dict, *x, *slots;
  	PyTypeObject *type, *base;
! 	static char *kwlist[] = {"name", "bases", "dict", 0};
  	etype *et;
  	struct memberlist *mp;
***************
*** 161,165 ****
  
  	/* Check arguments */
! 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", &dummy,
  					 &name, &bases, &dict))
  		return -1;
--- 163,167 ----
  
  	/* Check arguments */
! 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
  					 &name, &bases, &dict))
  		return -1;
***************
*** 170,192 ****
  	}
  	if (PyTuple_GET_SIZE(bases) > 1) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"can't multiple-inherit from types");
- 		return -1;
- 	}
- 	if (PyTuple_GET_SIZE(bases) < 1) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"can't create a new type without a base type");
- 		return -1;
- 	}
- 	base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0);
- 	if (!PyType_Check((PyObject *)base)) {
  		PyErr_SetString(PyExc_TypeError,
! 				"base type must be a type");
  		return -1;
  	}
! 	if (base->tp_init == NULL) {
! 		PyErr_SetString(PyExc_TypeError,
! 				"base type must have a constructor slot");
! 		return -1;
  	}
  
--- 172,193 ----
  	}
  	if (PyTuple_GET_SIZE(bases) > 1) {
  		PyErr_SetString(PyExc_TypeError,
! 				"can't multiple-inherit from types (yet)");
  		return -1;
  	}
! 	if (PyTuple_GET_SIZE(bases) < 1)
! 		base = &PyBaseObject_Type;
! 	else {
! 		base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0);
! 		if (!PyType_Check((PyObject *)base)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"base type must be a type");
! 			return -1;
! 		}
! 		if (base->tp_new == NULL) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"base type must have a tp_new slot");
! 			return -1;
! 		}
  	}
  
***************
*** 347,350 ****
--- 348,402 ----
  	offsetof(PyTypeObject, tp_dict),	/* tp_dictoffset */
  	type_init,				/* tp_init */
+ 	PyType_GenericAlloc,			/* tp_alloc */
+ 	PyType_GenericNew,			/* tp_new */
+ };
+ 
+ 
+ /* The base type of all types (eventually)... except itself. */
+ 
+ static void
+ object_dealloc(PyObject *self)
+ {
+ 	PyObject_Del(self);
+ }
+ 
+ PyTypeObject PyBaseObject_Type = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,					/* ob_size */
+ 	"object",				/* tp_name */
+ 	sizeof(PyObject),			/* tp_basicsize */
+ 	0,					/* tp_itemsize */
+ 	(destructor)object_dealloc,		/* tp_dealloc */
+ 	0,					/* tp_print */
+ 	0,			 		/* tp_getattr */
+ 	0,					/* tp_setattr */
+ 	0,					/* tp_compare */
+ 	0,					/* tp_repr */
+ 	0,					/* tp_as_number */
+ 	0,					/* tp_as_sequence */
+ 	0,					/* tp_as_mapping */
+ 	0,					/* tp_hash */
+ 	0,					/* tp_call */
+ 	0,					/* tp_str */
+ 	PyGeneric_GetAttr,			/* tp_getattro */
+ 	0,					/* tp_setattro */
+ 	0,					/* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	"The most base type",			/* tp_doc */
+ 	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
  	PyType_GenericAlloc,			/* tp_alloc */
  	PyType_GenericNew,			/* tp_new */