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

Moshe Zadka Moshe Zadka <mzadka@geocities.com>
Sat, 19 Feb 2000 06:31:51 +0200 (IST)


On Fri, 18 Feb 2000, Greg Stein wrote:

> My mailer isn't good with attachments, so I can't directly quote :-(

No problems: I'll inline it this time.

> * it looks like the indentation/tabbing in object.h for sq_contains is
>   different than the preceding lines. (in the diff, it shows at a
>   different indent level)

You're right, I had an extra whitespace there. Taken care of.

> * in abstract.c, you've got cascading "if" statements that could more
>   easily be written:
> 
>     if (sq != NULL && sq->sq_contains != NULL)

Right again. Changed.

> * in PyInstance_Type, you should use Py_TPFLAGS_DEFAULT. the slot 
>   structures *do* have those new slots once you compile them in the
>   presence of the updated object.h file.

Done.

Thanks a lot Greg.

Here's the new and updated version:
------------------- cut here ----------------
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	Fri Feb 18 18:47:55 2000
***************
*** 1065,1070 ****
--- 1065,1099 ----
  	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)
+ 		return -1;
+ 	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 ****
--- 1102,1108 ----
  	(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 ****
--- 1435,1442 ----
  	0,			/*tp_str*/
  	(getattrofunc)instance_getattr, /*tp_getattro*/
  	(setattrofunc)instance_setattr, /*tp_setattro*/
+         0, /* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT, /*tp_flags */
  };
  
--------------- cut here ------------------------------------  
Legal:
-- 
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.