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

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 15 May 2001 09:31:37 -0700


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

Modified Files:
      Tag: descr-branch
	typeobject.c 
Log Message:
Get rid of the extra metatypes DynamicType_Type and Turtle_Type.
These are now folded into the original Type_Type.

A separate flag (Py_TPFLAGS_HEAPTYPE) is set in type objects allocated
on the heap; if type_dealloc() is called for a type that doesn't have
this flag set, something's wrong!


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.21
retrieving revision 2.16.8.22
diff -C2 -r2.16.8.21 -r2.16.8.22
*** typeobject.c	2001/05/12 20:58:24	2.16.8.21
--- typeobject.c	2001/05/15 16:31:35	2.16.8.22
***************
*** 80,90 ****
  
  	res = (type->tp_construct)(obj, args, kwds);
! 	if (res != obj) {
  		Py_DECREF(obj);
! 		if (res == NULL)
! 			return NULL;
  	}
  	if (PyType_IS_GC(type))
  		PyObject_GC_Init(res);
  	return res;
  }
--- 80,105 ----
  
  	res = (type->tp_construct)(obj, args, kwds);
! 	if (res == NULL) {
  		Py_DECREF(obj);
! 		return NULL;
  	}
  	if (PyType_IS_GC(type))
  		PyObject_GC_Init(res);
+ 	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ 		PyObject *init, *dummy;
+ 
+ 		init = PyObject_GetAttrString(res, "__init__");
+ 		if (init == NULL) {
+ 			PyErr_Clear();
+ 			return res;
+ 		}
+ 		dummy = PyObject_Call(init, args, kwds);
+ 		Py_DECREF(init);
+ 		if (dummy == NULL) {
+ 			Py_DECREF(obj);
+ 			return NULL;
+ 		}
+ 		Py_DECREF(dummy);
+ 	}
  	return res;
  }
***************
*** 120,123 ****
--- 135,141 ----
  	destructor f;
  
+ 	/* XXX Alternatively, we could call tp_clear to clear the object;
+ 	   but this is not guaranteed to delete all pointers, just likely. */
+ 
  	base = self->ob_type->tp_base;
  	while ((f = base->tp_dealloc) == subtype_dealloc)
***************
*** 159,167 ****
  
  	/* Check arguments */
- 	if (type != NULL) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"can't construct a preallocated type");
- 		return NULL;
- 	}
  	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", &dummy,
  					 &name, &bases, &dict))
--- 177,180 ----
***************
*** 222,231 ****
  	/* Allocate memory and construct a type object in it */
  	allocsize = sizeof(etype) + nslots*sizeof(struct memberlist);
! 	et = PyObject_MALLOC(allocsize);
! 	if (et == NULL)
! 		return NULL;
! 	memset(et, '\0', allocsize);
! 	type = &et->type;
! 	PyObject_INIT(type, &PyDynamicType_Type);
  	Py_INCREF(name);
  	et->name = name;
--- 235,258 ----
  	/* Allocate memory and construct a type object in it */
  	allocsize = sizeof(etype) + nslots*sizeof(struct memberlist);
! 	if (type == NULL) {
! 		et = PyObject_MALLOC(allocsize);
! 		if (et == NULL)
! 			return NULL;
! 		memset(et, '\0', allocsize);
! 		type = &et->type;
! 		PyObject_INIT(type, &PyType_Type);
! 	}
! 	else {
! 		if (type->ob_type->tp_basicsize < allocsize) {
! 			PyErr_Format(
! 				PyExc_SystemError,
! 				"insufficient allocated memory for subtype: "
! 				"allocated %d, needed %d",
! 				type->ob_type->tp_basicsize,
! 				allocsize);
! 			return NULL;
! 		}
! 		et = (etype *)type;
! 	}
  	Py_INCREF(name);
  	et->name = name;
***************
*** 236,240 ****
  	type->tp_as_buffer = &et->as_buffer;
  	type->tp_name = PyString_AS_STRING(name);
! 	type->tp_flags = Py_TPFLAGS_DEFAULT;
  
  	/* Copy slots and dict from the base type */
--- 263,267 ----
  	type->tp_as_buffer = &et->as_buffer;
  	type->tp_name = PyString_AS_STRING(name);
! 	type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
  
  	/* Copy slots and dict from the base type */
***************
*** 294,367 ****
  }
  
- PyTypeObject PyType_Type = {
- 	PyObject_HEAD_INIT(&PyTurtle_Type)
- 	0,			/* Number of items for varobject */
- 	"type",			/* Name of this type */
- 	sizeof(PyTypeObject),	/* Basic object size */
- 	0,			/* Item size for varobject */
- 	0,					/* tp_dealloc */
- 	0,					/* tp_print */
- 	0,			 		/* tp_getattr */
- 	0,					/* tp_setattr */
- 	0,					/* tp_compare */
- 	(reprfunc)type_repr,			/* tp_repr */
- 	0,					/* tp_as_number */
- 	0,					/* tp_as_sequence */
- 	0,					/* tp_as_mapping */
- 	0,					/* tp_hash */
- 	(ternaryfunc)type_call,			/* tp_call */
- 	0,					/* tp_str */
- 	PyGeneric_GetAttr,			/* tp_getattro */
- 	0,					/* tp_setattro */
- 	0,					/* tp_as_buffer */
- 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
- 	"Define the behavior of a particular type of object.", /* tp_doc */
- 	0,					/* tp_traverse */
- 	0,					/* tp_clear */
- 	0,					/* tp_richcompare */
- 	0,					/* tp_weaklistoffset */
- 	0,					/* tp_iter */
- 	0,					/* tp_iternext */
- 	0,					/* tp_methods */
- 	type_members,				/* tp_members */
- 	type_getsets,				/* tp_getset */
- 	0,					/* tp_base */
- 	0,					/* tp_dict */
- 	0,					/* tp_descr_get */
- 	0,					/* tp_descr_set */
- 	(ternaryfunc)type_construct,		/* tp_construct */
- 	offsetof(PyTypeObject, tp_dict),	/* tp_dictoffset */
- };
- 
- /* Support for dynamic types, created by type_construct() above */
- 
- static PyObject *
- dtype_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- 	PyObject *newobj, *init, *res;
- 
- 	newobj = type_call(type, args, kwds);
- 	if (newobj == NULL)
- 		return NULL;
- 	init = PyObject_GetAttrString(newobj, "__init__");
- 	if (init == NULL) {
- 		PyErr_Clear();
- 		return newobj;
- 	}
- 	res = PyObject_Call(init, args, kwds);
- 	Py_DECREF(init);
- 	if (res == NULL) {
- 		Py_DECREF(newobj);
- 		return NULL;
- 	}
- 	Py_DECREF(res);
- 	return newobj;
- }
- 
  static void
! dtype_dealloc(PyTypeObject *type)
  {
! 	etype *et = (etype *)type;
  
  	Py_XDECREF(type->tp_base);
  	Py_XDECREF(type->tp_dict);
--- 321,333 ----
  }
  
  static void
! type_dealloc(PyTypeObject *type)
  {
! 	etype *et;
  
+ 	/* Assert this is a heap-allocated type object, or uninitialized */
+ 	if (type->tp_flags != 0)
+ 		assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+ 	et = (etype *)type;
  	Py_XDECREF(type->tp_base);
  	Py_XDECREF(type->tp_dict);
***************
*** 371,451 ****
  }
  
! PyTypeObject PyDynamicType_Type = {
! 	PyObject_HEAD_INIT(&PyTurtle_Type)
! 	0,			/* Number of items for varobject */
! 	"dynamic-type",		/* Name of this type */
! 	sizeof(PyTypeObject),	/* Basic object size */
! 	0,			/* Item size for varobject */
! 	(destructor)dtype_dealloc,		/* tp_dealloc */
! 	0,					/* tp_print */
! 	0,			 		/* tp_getattr */
! 	0,					/* tp_setattr */
! 	0,					/* tp_compare */
! 	(reprfunc)type_repr,			/* tp_repr */
! 	0,					/* tp_as_number */
! 	0,					/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	0,					/* tp_hash */
! 	(ternaryfunc)dtype_call,		/* tp_call */
! 	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
! 	PyGeneric_SetAttr,			/* tp_setattro */
! 	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
! 	"Define the behavior of a particular type of object.", /* tp_doc */
! 	0,					/* tp_traverse */
! 	0,					/* tp_clear */
! 	0,					/* tp_richcompare */
! 	0,					/* tp_weaklistoffset */
! 	0,					/* tp_iter */
! 	0,					/* tp_iternext */
! 	0,					/* tp_methods */
! 	type_members,				/* tp_members */
! 	type_getsets,				/* tp_getset */
! 	&PyType_Type,				/* tp_base */
! 	0,					/* tp_dict */
! 	0,					/* tp_descr_get */
! 	0,					/* tp_descr_set */
! 	(ternaryfunc)type_construct,		/* tp_construct */
! 	offsetof(PyTypeObject, tp_dict),	/* tp_dictoffset */
! };
! 
! 
! /* The "turtle" type is named after the expression "turtles all the way down",
!    a reference to the fact that it is its own type.  We get the progression:
!    x                => {} # for example
!    type(x)          => DictType
!    type(DictType)   => TypeType
!    type(TypeType)   => TurtleType
!    type(TurtleType) => TurtleType
!    type(TurtleType) => TurtleType
!    type(TurtleType) => TurtleType
!    .
!    .
!    .
!    It's from an old story often told about Bertrand Russel, popularized most
!    recently by Stephen Hawking; do a Google search for the phrase to find out
!    more.  The oldest turtle reference in the Python archives seems to be:
!    http://mail.python.org/pipermail/types-sig/1998-November/000084.html */
! 
! static PyObject *
! turtle_call(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
! {
! 	if (metatype->tp_construct == NULL) {
! 		PyErr_Format(PyExc_TypeError,
! 			     "can't subclass '.%100s' objects yet",
! 			     metatype->tp_name);
! 		return NULL;
! 	}
! 	return (*metatype->tp_construct)(NULL, args, kwds);
! }
! 
! PyTypeObject PyTurtle_Type = {
! 	PyObject_HEAD_INIT(&PyTurtle_Type)
  	0,			/* Number of items for varobject */
! 	"turtle",		/* Name of this type */
! 	sizeof(PyTypeObject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	0,					/* tp_dealloc */
  	0,					/* tp_print */
  	0,			 		/* tp_getattr */
--- 337,347 ----
  }
  
! 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 */
  	0,			 		/* tp_getattr */
***************
*** 457,461 ****
  	0,					/* tp_as_mapping */
  	0,					/* tp_hash */
! 	(ternaryfunc)turtle_call,		/* tp_call */
  	0,					/* tp_str */
  	PyGeneric_GetAttr,			/* tp_getattro */
--- 353,357 ----
  	0,					/* tp_as_mapping */
  	0,					/* tp_hash */
! 	(ternaryfunc)type_call,			/* tp_call */
  	0,					/* tp_str */
  	PyGeneric_GetAttr,			/* tp_getattro */
***************
*** 473,481 ****
  	type_members,				/* tp_members */
  	type_getsets,				/* tp_getset */
! 	&PyType_Type,				/* tp_base */
  	0,					/* tp_dict */
  	0,					/* tp_descr_get */
  	0,					/* tp_descr_set */
! 	0,					/* tp_construct */
  	offsetof(PyTypeObject, tp_dict),	/* tp_dictoffset */
  };
--- 369,377 ----
  	type_members,				/* tp_members */
  	type_getsets,				/* tp_getset */
! 	0,					/* tp_base */
  	0,					/* tp_dict */
  	0,					/* tp_descr_get */
  	0,					/* tp_descr_set */
! 	(ternaryfunc)type_construct,		/* tp_construct */
  	offsetof(PyTypeObject, tp_dict),	/* tp_dictoffset */
  };