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

Guido van Rossum gvanrossum@users.sourceforge.net
Mon, 21 May 2001 14:31:52 -0700


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

Modified Files:
      Tag: descr-branch
	typeobject.c 
Log Message:
INCREF the type object in type_call() when the type object is
allocated on the heap.  This removes the need for subtype_construct()
(which existed *just* to INCREF self->ob_type).  We still need
subtype_dealloc() to do the matching DECREF, because the base type's
dealloc won't do this.

I don't want to require all types to INCREF the type object for each
object they own, but we do need this for type objects allocated on the
heap.  Doing the INCREF in subtype_construct was too late, because if
subtype_construct() failed, type_call() would DECREF the partially
initialized object, which would invoke subtype_dealloc(), which would
incorrect DECREF'ed the type object.  The only safe thing to do is to
INCREF the type in type_call(), which this patch does.

Also correct a bug in subtype_dealloc(), which would call
base->tp_dealloc, even though it intended to call f, which it had
calculated as the first base->base->...->tp_dealloc found that wasn't
subtype_dealloc.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.22
retrieving revision 2.16.8.23
diff -C2 -r2.16.8.22 -r2.16.8.23
*** typeobject.c	2001/05/15 16:31:35	2.16.8.22
--- typeobject.c	2001/05/21 21:31:50	2.16.8.23
***************
*** 77,80 ****
--- 77,82 ----
  	else
  		obj = (PyObject *)mem;
+ 	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ 		Py_INCREF(type);
  	PyObject_INIT(obj, type);
  
***************
*** 105,131 ****
  }
  
! /* Helpers for subtyping */
  
- static PyObject *
- subtype_construct(PyObject *self, PyObject *args, PyObject *kwds)
- {
- 	PyObject *res;
- 	PyTypeObject *base;
- 	ternaryfunc f;
- 
- 	if (self == NULL) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"can't allocate subtype instances");
- 		return NULL;
- 	}
- 	base = self->ob_type->tp_base;
- 	while ((f = base->tp_construct) == subtype_construct)
- 		base = base->tp_base;
- 	res = f(self, args, kwds);
- 	if (res == self)
- 		Py_INCREF(self->ob_type);
- 	return res;
- }
- 
  static void
  subtype_dealloc(PyObject *self)
--- 107,112 ----
  }
  
! /* Helper for subtyping */
  
  static void
  subtype_dealloc(PyObject *self)
***************
*** 135,140 ****
  	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;
--- 116,120 ----
  	destructor f;
  
! 	/* This exists so we can DECREF self->ob_type */
  
  	base = self->ob_type->tp_base;
***************
*** 148,154 ****
  			*dictptr = NULL;
  		}
  	}
- 	base->tp_dealloc(self);
- 	Py_DECREF(self->ob_type);
  }
  
--- 128,136 ----
  			*dictptr = NULL;
  		}
+ 	}
+ 	f(self);
+ 	if (self->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ 		Py_DECREF(self->ob_type);
  	}
  }
  
***************
*** 274,279 ****
  
  	/* Override some slots with specific requirements */
- 	if (type->tp_construct)
- 		type->tp_construct = subtype_construct;
  	if (type->tp_dealloc)
  		type->tp_dealloc = subtype_dealloc;
--- 256,259 ----