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

Guido van Rossum gvanrossum@users.sourceforge.net
Fri, 17 Aug 2001 09:47:52 -0700


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

Modified Files:
	typeobject.c 
Log Message:
type_new(): look for __dynamic__ at the module level (after looking in
the class dict).  Anything but a nonnegative int in either place is
*ignored* (before, a non-Boolean was an error).  The default is still
static -- in a comparative test, Jeremy's Tools/compiler package ran
twice as slow (compiling itself) using dynamic as the default.  (The
static version, which requires a few tweaks to avoid modifying class
variables, runs at about the same speed as the classic version.)

slot_tp_descr_get(): this also needed fallback behavior.

slot_tp_getattro(): remove a debug fprintf() call.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.39
retrieving revision 2.40
diff -C2 -d -r2.39 -r2.40
*** typeobject.c	2001/08/17 11:18:38	2.39
--- typeobject.c	2001/08/17 16:47:50	2.40
***************
*** 567,587 ****
  	}
  
! 	/* Should this be a dynamic class (i.e. modifiable __dict__)? */
  	tmp = PyDict_GetItemString(dict, "__dynamic__");
  	if (tmp != NULL) {
! 		/* The class author has a preference */
! 		dynamic = PyObject_IsTrue(tmp);
! 		Py_DECREF(tmp);
  		if (dynamic < 0)
! 			return NULL;
  	}
! 	else {
! 		/* Make a new class dynamic if any of its bases is dynamic.
! 		   This is not always the same as inheriting the __dynamic__
! 		   class attribute! */
  		dynamic = 0;
  		for (i = 0; i < nbases; i++) {
! 			tmptype = (PyTypeObject *)PyTuple_GET_ITEM(bases, i);
! 			if (tmptype->tp_flags & Py_TPFLAGS_DYNAMICTYPE) {
  				dynamic = 1;
  				break;
--- 567,608 ----
  	}
  
! 	/* Should this be a dynamic class (i.e. modifiable __dict__)?
! 	   Look in two places for a variable named __dynamic__:
! 	   1) in the class dict
! 	   2) in the module dict (globals)
! 	   The first variable that is an int >= 0 is used.
! 	   Otherwise, a default is calculated from the base classes:
! 	   if any base class is dynamic, this class is dynamic; otherwise
! 	   it is static. */
! 	dynamic = -1; /* Not yet determined */
! 	/* Look in the class */
  	tmp = PyDict_GetItemString(dict, "__dynamic__");
  	if (tmp != NULL) {
! 		dynamic = PyInt_AsLong(tmp);
  		if (dynamic < 0)
! 			PyErr_Clear();
  	}
! 	if (dynamic < 0) {
! 		/* Look in the module globals */
! 		tmp = PyEval_GetGlobals();
! 		if (tmp != NULL) {
! 			tmp = PyDict_GetItemString(tmp, "__dynamic__");
! 			if (tmp != NULL) {
! 				dynamic = PyInt_AsLong(tmp);
! 				if (dynamic < 0)
! 					PyErr_Clear();
! 			}
! 		}
! 	}
! 	if (dynamic < 0) {
! 		/* Make a new class dynamic if any of its bases is
! 		   dynamic.  This is not always the same as inheriting
! 		   the __dynamic__ class attribute! */
  		dynamic = 0;
  		for (i = 0; i < nbases; i++) {
! 			tmptype = (PyTypeObject *)
! 				PyTuple_GET_ITEM(bases, i);
! 			if (tmptype->tp_flags &
! 			    Py_TPFLAGS_DYNAMICTYPE) {
  				dynamic = 1;
  				break;
***************
*** 2566,2571 ****
  		if (tp->tp_getattro == slot_tp_getattro)
  			tp->tp_getattro = PyObject_GenericGetAttr;
- 		else
- 			fprintf(stderr, "huh?\n");
  		return PyObject_GenericGetAttr(self, name);
  	}
--- 2587,2590 ----
***************
*** 2673,2677 ****
  }
  
! SLOT2(slot_tp_descr_get, "__get__", PyObject *, PyObject *, "OO")
  
  static int
--- 2692,2717 ----
  }
  
! static PyObject *
! slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
! {
! 	PyTypeObject *tp = self->ob_type;
! 	PyObject *get;
! 	static PyObject *get_str = NULL;
! 
! 	if (get_str == NULL) {
! 		get_str = PyString_InternFromString("__get__");
! 		if (get_str == NULL)
! 			return NULL;
! 	}
! 	get = _PyType_Lookup(tp, get_str);
! 	if (get == NULL) {
! 		/* Avoid further slowdowns */
! 		if (tp->tp_descr_get == slot_tp_descr_get)
! 			tp->tp_descr_get = NULL;
! 		Py_INCREF(self);
! 		return self;
! 	}
! 	return PyObject_CallFunction(get, "OOO", self, obj, type);
! }
  
  static int