[Patches] in-overloading: done right, with Guido's comments folded in

Moshe Zadka Moshe Zadka <mzadka@geocities.com>
Sat, 19 Feb 2000 15:09:45 +0200 (IST)


OK, here's another version:

(Same checkin message from last e-mail, the only change is a bug fix)

--
diff -c -r python/dist/src/Include/object.h build/dist/src/Include/object.h
*** python/dist/src/Include/object.h	Wed Feb  2 16:02:51 2000
--- build/dist/src/Include/object.h	Fri Feb 18 18:46:46 2000
***************
*** 150,155 ****
--- 150,156 ----
  typedef int (*getwritebufferproc) Py_PROTO((PyObject *, int, void **));
  typedef int (*getsegcountproc) Py_PROTO((PyObject *, int *));
  typedef int (*getcharbufferproc) Py_PROTO((PyObject *, int, const char **));
+ typedef int (*objobjproc) Py_PROTO((PyObject *, PyObject *));
  
  typedef struct {
  	binaryfunc nb_add;
***************
*** 185,190 ****
--- 186,192 ----
  	intintargfunc sq_slice;
  	intobjargproc sq_ass_item;
  	intintobjargproc sq_ass_slice;
+ 	objobjproc sq_contains;
  } PySequenceMethods;
  
  typedef struct {
***************
*** 317,323 ****
  /* PyBufferProcs contains bf_getcharbuffer */
  #define Py_TPFLAGS_HAVE_GETCHARBUFFER  (1L<<0)
  
! #define Py_TPFLAGS_DEFAULT  (Py_TPFLAGS_HAVE_GETCHARBUFFER)
  
  #define PyType_HasFeature(t,f)  (((t)->tp_flags & (f)) != 0)
  
--- 319,329 ----
  /* PyBufferProcs contains bf_getcharbuffer */
  #define Py_TPFLAGS_HAVE_GETCHARBUFFER  (1L<<0)
  
! /* PySequenceMethods contains sq_contains */
! #define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1)
! 
! #define Py_TPFLAGS_DEFAULT  (Py_TPFLAGS_HAVE_GETCHARBUFFER | \
!                              Py_TPFLAGS_HAVE_SEQUENCE_IN)
  
  #define PyType_HasFeature(t,f)  (((t)->tp_flags & (f)) != 0)
  
diff -c -r python/dist/src/Objects/abstract.c build/dist/src/Objects/abstract.c
*** python/dist/src/Objects/abstract.c	Fri Feb 18 09:06:45 2000
--- build/dist/src/Objects/abstract.c	Fri Feb 18 18:47:23 2000
***************
*** 1121,1127 ****
  		}
  		return 0;
  	}
! 
  	sq = w->ob_type->tp_as_sequence;
  	if (sq == NULL || sq->sq_item == NULL) {
  		PyErr_SetString(PyExc_TypeError,
--- 1121,1134 ----
  		}
  		return 0;
  	}
! 	if(PyType_HasFeature(w->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
! 		sq = w->ob_type->tp_as_sequence;
! 	        if(sq != NULL && sq->sq_contains != NULL)
! 			return (*sq->sq_contains)(w, v);
! 	}
! 	
! 	/* If there is no better way to check whether an item is is contained,
! 	   do it the hard way */
  	sq = w->ob_type->tp_as_sequence;
  	if (sq == NULL || sq->sq_item == NULL) {
  		PyErr_SetString(PyExc_TypeError,
diff -c -r python/dist/src/Objects/classobject.c build/dist/src/Objects/classobject.c
*** python/dist/src/Objects/classobject.c	Fri Feb 18 09:06:49 2000
--- build/dist/src/Objects/classobject.c	Sat Feb 19 03:17:46 2000
***************
*** 1065,1070 ****
--- 1065,1123 ----
  	return 0;
  }
  
+ static int instance_contains(PyInstanceObject *inst, PyObject *member)
+ {
+ 	static PyObject *__contains__;
+ 	PyObject *func, *arg, *res;
+ 	int ret;
+ 
+ 	if(__contains__ == NULL) {
+ 		__contains__ = PyString_InternFromString("__contains__");
+ 		if(__contains__ == NULL)
+ 			return -1;
+ 	}
+ 	func = instance_getattr(inst, __contains__);
+ 	if(func == NULL) {
+ 		/* fall back to previous behaviour */
+ 		int i, cmp_res;
+ 
+ 		if(!PyErr_ExceptionMatches(PyExc_AttributeError))
+ 			return -1;
+ 		PyErr_Clear();
+ 		for(i=0;;i++) {
+ 			PyObject *obj = instance_item(inst, i);
+ 			int ret = 0;
+ 
+ 			if(obj == NULL) {
+ 				if(!PyErr_ExceptionMatches(PyExc_IndexError))
+ 					return -1;
+ 				PyErr_Clear();
+ 				return 0;
+ 			}
+ 			if(PyObject_Cmp(obj, member, &cmp_res) == -1)
+ 				ret = -1;
+ 			if(cmp_res == 0) 
+ 				ret = 1;
+ 			Py_DECREF(obj);
+ 			if(ret)
+ 				return ret;
+ 		}
+ 	}
+ 	arg = Py_BuildValue("(O)", member);
+ 	if(arg == NULL) {
+ 		Py_DECREF(func);
+ 		return -1;
+ 	}
+ 	res = PyEval_CallObject(func, arg);
+ 	Py_DECREF(func);
+ 	Py_DECREF(arg);
+ 	if(res == NULL) 
+ 		return -1;
+ 	ret = PyObject_IsTrue(res);
+ 	Py_DECREF(res);
+ 	return ret;
+ }
+ 
  static PySequenceMethods instance_as_sequence = {
  	(inquiry)instance_length, /*sq_length*/
  	0, /*sq_concat*/
***************
*** 1073,1078 ****
--- 1126,1132 ----
  	(intintargfunc)instance_slice, /*sq_slice*/
  	(intobjargproc)instance_ass_item, /*sq_ass_item*/
  	(intintobjargproc)instance_ass_slice, /*sq_ass_slice*/
+ 	(objobjproc)instance_contains, /* sq_contains */
  };
  
  static PyObject *
***************
*** 1405,1410 ****
--- 1459,1466 ----
  	0,			/*tp_str*/
  	(getattrofunc)instance_getattr, /*tp_getattro*/
  	(setattrofunc)instance_setattr, /*tp_setattro*/
+         0, /* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT, /*tp_flags */
  };
  
---

--
Legalese:
I confirm that, to the best of my knowledge and belief, this contribution is
free of any claims of third parties under copyright, patent or other rights
or interests ("claims").  To the extent that I have any such claims, I
hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide
license to reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part of the
Python software and its related documentation, or any derivative versions
thereof, at no cost to CNRI or its licensed users, and to authorize others
to do so.

I acknowledge that CNRI may, at its sole discretion, decide whether or not
to incorporate this contribution in the Python software and its related
documentation.  I further grant CNRI permission to use my name and other
identifying information provided to CNRI by me for use in connection with
the Python software and its related documentation.


--
Moshe Zadka <mzadka@geocities.com>. 
INTERNET: Learn what you know.
Share what you don't.