[Python-checkins] python/dist/src/Objects funcobject.c,2.60,2.61

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
Tue, 08 Apr 2003 14:28:52 -0700


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

Modified Files:
	funcobject.c 
Log Message:
Make staticmethods and classmethods participate in GC.

If a class was defined inside a function, used a static or class
method, and used super() inside the method body, it would be caught in
an uncollectable cycle.  (Simplified version: The static/class method
object would point to a function object with a closure that referred
to the class.)

Bugfix candidate.


Index: funcobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v
retrieving revision 2.60
retrieving revision 2.61
diff -C2 -d -r2.60 -r2.61
*** funcobject.c	18 Feb 2003 17:18:35 -0000	2.60
--- funcobject.c	8 Apr 2003 21:28:47 -0000	2.61
***************
*** 591,598 ****
--- 591,617 ----
  cm_dealloc(classmethod *cm)
  {
+ 	_PyObject_GC_UNTRACK((PyObject *)cm);
  	Py_XDECREF(cm->cm_callable);
  	cm->ob_type->tp_free((PyObject *)cm);
  }
  
+ static int
+ cm_traverse(classmethod *cm, visitproc visit, void *arg)
+ {
+ 	if (!cm->cm_callable)
+ 		return 0;
+ 	return visit(cm->cm_callable, arg);
+ }
+ 
+ static int
+ cm_clear(classmethod *cm)
+ {
+ 	Py_XDECREF(cm->cm_callable);
+ 	cm->cm_callable = NULL;
+ 
+ 	return 0;
+ }
+ 
+ 
  static PyObject *
  cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
***************
*** 666,673 ****
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
  	classmethod_doc,			/* tp_doc */
! 	0,					/* tp_traverse */
! 	0,					/* tp_clear */
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
--- 685,692 ----
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
  	classmethod_doc,			/* tp_doc */
! 	(traverseproc)cm_traverse,		/* tp_traverse */
! 	(inquiry)cm_clear,			/* tp_clear */
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
***************
*** 685,689 ****
  	PyType_GenericAlloc,			/* tp_alloc */
  	PyType_GenericNew,			/* tp_new */
! 	PyObject_Del,		                /* tp_free */
  };
  
--- 704,708 ----
  	PyType_GenericAlloc,			/* tp_alloc */
  	PyType_GenericNew,			/* tp_new */
! 	PyObject_GC_Del,	                /* tp_free */
  };
  
***************
*** 725,732 ****
--- 744,769 ----
  sm_dealloc(staticmethod *sm)
  {
+ 	_PyObject_GC_UNTRACK((PyObject *)sm);
  	Py_XDECREF(sm->sm_callable);
  	sm->ob_type->tp_free((PyObject *)sm);
  }
  
+ static int
+ sm_traverse(staticmethod *sm, visitproc visit, void *arg)
+ {
+ 	if (!sm->sm_callable)
+ 		return 0;
+ 	return visit(sm->sm_callable, arg);
+ }
+ 
+ static int
+ sm_clear(staticmethod *sm)
+ {
+ 	Py_XDECREF(sm->sm_callable);
+ 	sm->sm_callable = NULL;
+ 
+ 	return 0;
+ }
+ 
  static PyObject *
  sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
***************
*** 795,802 ****
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
  	staticmethod_doc,			/* tp_doc */
! 	0,					/* tp_traverse */
! 	0,					/* tp_clear */
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
--- 832,839 ----
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
  	staticmethod_doc,			/* tp_doc */
! 	(traverseproc)sm_traverse,		/* tp_traverse */
! 	(inquiry)sm_clear,			/* tp_clear */
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
***************
*** 814,818 ****
  	PyType_GenericAlloc,			/* tp_alloc */
  	PyType_GenericNew,			/* tp_new */
! 	PyObject_Del,           		/* tp_free */
  };
  
--- 851,855 ----
  	PyType_GenericAlloc,			/* tp_alloc */
  	PyType_GenericNew,			/* tp_new */
! 	PyObject_GC_Del,           		/* tp_free */
  };