[Python-checkins] CVS: python/dist/src/Objects classobject.c,2.130,2.131

Jeremy Hylton jhylton@users.sourceforge.net
Fri, 11 May 2001 07:48:43 -0700


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

Modified Files:
	classobject.c 
Log Message:
Variant of SF patch 423181

For rich comparisons, use instance_getattr2() when possible to avoid
the expense of setting an AttributeError.  Also intern the name_op[]
table and use the interned strings rather than creating a new string
and interning it each time through.


Index: classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.130
retrieving revision 2.131
diff -C2 -r2.130 -r2.131
*** classobject.c	2001/05/05 21:05:01	2.130
--- classobject.c	2001/05/11 14:48:41	2.131
***************
*** 1652,1668 ****
  
  /* Map rich comparison operators to their __xx__ namesakes */
! static char *name_op[] = {
! 	"__lt__",
! 	"__le__",
! 	"__eq__",
! 	"__ne__",
! 	"__gt__",
! 	"__ge__",
! };
  
  static PyObject *
  half_richcompare(PyObject *v, PyObject *w, int op)
  {
- 	PyObject *name;
  	PyObject *method;
  	PyObject *args;
--- 1652,1685 ----
  
  /* Map rich comparison operators to their __xx__ namesakes */
! #define NAME_OPS 6
! static PyObject **name_op = NULL;
  
+ static int 
+ init_name_op()
+ {
+ 	int i;
+ 	char *_name_op[] = {
+ 		"__lt__",
+ 		"__le__",
+ 		"__eq__",
+ 		"__ne__",
+ 		"__gt__",
+ 		"__ge__",
+ 	};
+ 
+ 	name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS);
+ 	if (name_op == NULL)
+ 		return -1;
+ 	for (i = 0; i < NAME_OPS; ++i) {
+ 		name_op[i] = PyString_InternFromString(_name_op[i]);
+ 		if (name_op[i] == NULL)
+ 			return -1;
+ 	}
+ 	return 0;
+ }
+ 
  static PyObject *
  half_richcompare(PyObject *v, PyObject *w, int op)
  {
  	PyObject *method;
  	PyObject *args;
***************
*** 1670,1687 ****
  
  	assert(PyInstance_Check(v));
- 
- 	name = PyString_InternFromString(name_op[op]);
- 	if (name == NULL)
- 		return NULL;
  
! 	method = PyObject_GetAttr(v, name);
! 	Py_DECREF(name);
! 	if (method == NULL) {
! 		if (!PyErr_ExceptionMatches(PyExc_AttributeError))
  			return NULL;
! 		PyErr_Clear();
! 		res = Py_NotImplemented;
! 		Py_INCREF(res);
! 		return res;
  	}
  
--- 1687,1717 ----
  
  	assert(PyInstance_Check(v));
  
! 	if (name_op == NULL) {
! 		if (init_name_op() < 0)
  			return NULL;
! 	}
! 	/* If the instance doesn't define an __getattr__ method, use
! 	   instance_getattr2 directly because it will not set an
! 	   exception on failure. */
! 	if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) {
! 		method = instance_getattr2((PyInstanceObject *)v, 
! 					   name_op[op]);
! 		if (method == NULL) {
! 			assert(!PyErr_Occurred());
! 			res = Py_NotImplemented;
! 			Py_INCREF(res);
! 			return res;
! 		}
! 	} else {
! 		method = PyObject_GetAttr(v, name_op[op]);
! 		if (method == NULL) {
! 			if (!PyErr_ExceptionMatches(PyExc_AttributeError))
! 				return NULL;
! 			PyErr_Clear();
! 			res = Py_NotImplemented;
! 			Py_INCREF(res);
! 			return res;
! 		}
  	}