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

Guido van Rossum gvanrossum@users.sourceforge.net
Wed, 08 Aug 2001 15:26:24 -0700


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

Modified Files:
	typeobject.c 
Log Message:
Proper support for binary operators, including true division and floor
division.  The basic binary operators now all correctly call the
__rxxx__ variant when they should.

In type_new(), I now make the new type a new-style number unless it
inherits from an old-style number that has numeric methods.

By way of cosmetics, I've changed the signatures of the SLOT<i> macros
to take actual function names and operator names as strings, rather
than rely on C preprocessor symbol manipulations.  This makes the
calls slightly more verbose, but greatly helps simple searches through
the file: you can now find out where "__radd__" is used or where the
function slot_nb_power() is defined and where it is used.


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.24
retrieving revision 2.25
diff -C2 -d -r2.24 -r2.25
*** typeobject.c	2001/08/08 15:29:49	2.24
--- typeobject.c	2001/08/08 22:26:22	2.25
***************
*** 584,592 ****
  	et->slots = slots;
  
! 	/* Initialize essential fields */
  	type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
  		Py_TPFLAGS_BASETYPE;
  	if (dynamic)
  		type->tp_flags |= Py_TPFLAGS_DYNAMICTYPE;
  	type->tp_as_number = &et->as_number;
  	type->tp_as_sequence = &et->as_sequence;
--- 584,600 ----
  	et->slots = slots;
  
! 	/* Initialize tp_flags */
  	type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
  		Py_TPFLAGS_BASETYPE;
  	if (dynamic)
  		type->tp_flags |= Py_TPFLAGS_DYNAMICTYPE;
+ 
+ 	/* It's a new-style number unless it specifically inherits any
+ 	   old-style numeric behavior */
+ 	if ((base->tp_flags & Py_TPFLAGS_CHECKTYPES) ||
+ 	    (base->tp_as_number == NULL))
+ 		type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
+ 
+ 	/* Initialize essential fields */
  	type->tp_as_number = &et->as_number;
  	type->tp_as_sequence = &et->as_sequence;
***************
*** 1045,1048 ****
--- 1053,1062 ----
  		COPYNUM(nb_inplace_xor);
  		COPYNUM(nb_inplace_or);
+ 		if (base->tp_flags & Py_TPFLAGS_CHECKTYPES) {
+ 			COPYNUM(nb_true_divide);
+ 			COPYNUM(nb_floor_divide);
+ 			COPYNUM(nb_inplace_true_divide);
+ 			COPYNUM(nb_inplace_floor_divide);
+ 		}
  	}
  
***************
*** 2014,2037 ****
     below at override_slots() for more explanation. */
  
! #define SLOT0(SLOTNAME, OPNAME) \
  static PyObject * \
! slot_##SLOTNAME(PyObject *self) \
  { \
! 	return PyObject_CallMethod(self, "__" #OPNAME "__", ""); \
  }
  
! #define SLOT1(SLOTNAME, OPNAME, ARG1TYPE, ARGCODES) \
  static PyObject * \
! slot_##SLOTNAME(PyObject *self, ARG1TYPE arg1) \
  { \
! 	return PyObject_CallMethod(self, "__" #OPNAME "__", #ARGCODES, arg1); \
  }
  
! #define SLOT2(SLOTNAME, OPNAME, ARG1TYPE, ARG2TYPE, ARGCODES) \
  static PyObject * \
! slot_##SLOTNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \
  { \
! 	return PyObject_CallMethod(self, "__" #OPNAME "__", \
!                #ARGCODES, arg1, arg2); \
  }
  
--- 2028,2077 ----
     below at override_slots() for more explanation. */
  
! #define SLOT0(FUNCNAME, OPSTR) \
  static PyObject * \
! FUNCNAME(PyObject *self) \
  { \
! 	return PyObject_CallMethod(self, OPSTR, ""); \
  }
  
! #define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \
  static PyObject * \
! FUNCNAME(PyObject *self, ARG1TYPE arg1) \
  { \
! 	return PyObject_CallMethod(self, OPSTR, ARGCODES, arg1); \
  }
  
! 
! #define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
  static PyObject * \
! FUNCNAME(PyObject *self, PyObject *other) \
  { \
! 	if (self->ob_type->tp_as_number != NULL && \
! 	    self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
! 		PyObject *r; \
! 		r = PyObject_CallMethod( \
! 			self, OPSTR, "O", other); \
! 		if (r != Py_NotImplemented || \
! 		    other->ob_type == self->ob_type) \
! 			return r; \
! 		Py_DECREF(r); \
! 	} \
! 	if (other->ob_type->tp_as_number != NULL && \
! 	    other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
! 		return PyObject_CallMethod( \
! 			other, ROPSTR, "O", self); \
! 	} \
! 	Py_INCREF(Py_NotImplemented); \
! 	return Py_NotImplemented; \
! }
! 
! #define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \
! 	SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR)
! 
! #define SLOT2(FUNCNAME, OPSTR, ARG1TYPE, ARG2TYPE, ARGCODES) \
! static PyObject * \
! FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \
! { \
! 	return PyObject_CallMethod(self, OPSTR, ARGCODES, arg1, arg2); \
  }
  
***************
*** 2046,2053 ****
  }
  
! SLOT1(sq_concat, add, PyObject *, O)
! SLOT1(sq_repeat, mul, int, i)
! SLOT1(sq_item, getitem, int, i)
! SLOT2(sq_slice, getslice, int, int, ii)
  
  static int
--- 2086,2093 ----
  }
  
! SLOT1(slot_sq_concat, "__add__", PyObject *, "O")
! SLOT1(slot_sq_repeat, "__mul__", int, "i")
! SLOT1(slot_sq_item, "__getitem__", int, "i")
! SLOT2(slot_sq_slice, "__getslice__", int, int, "ii")
  
  static int
***************
*** 2096,2105 ****
  }
  
! SLOT1(sq_inplace_concat, iadd, PyObject *, O)
! SLOT1(sq_inplace_repeat, imul, int, i)
  
  #define slot_mp_length slot_sq_length
  
! SLOT1(mp_subscript, getitem, PyObject *, O)
  
  static int
--- 2136,2145 ----
  }
  
! SLOT1(slot_sq_inplace_concat, "__iadd__", PyObject *, "O")
! SLOT1(slot_sq_inplace_repeat, "__imul__", int, "i")
  
  #define slot_mp_length slot_sq_length
  
! SLOT1(slot_mp_subscript, "__getitem__", PyObject *, "O")
  
  static int
***************
*** 2119,2135 ****
  }
  
! /* XXX the numerical slots should call the reverse operators too;
!    but how do they know their type? */
! SLOT1(nb_add, add, PyObject *, O)
! SLOT1(nb_subtract, sub, PyObject *, O)
! SLOT1(nb_multiply, mul, PyObject *, O)
! SLOT1(nb_divide, div, PyObject *, O)
! SLOT1(nb_remainder, mod, PyObject *, O)
! SLOT1(nb_divmod, divmod, PyObject *, O)
! SLOT2(nb_power, pow, PyObject *, PyObject *, OO)
! SLOT0(nb_negative, neg)
! SLOT0(nb_positive, pos)
! SLOT0(nb_absolute, abs)
  
  static int
  slot_nb_nonzero(PyObject *self)
--- 2159,2187 ----
  }
  
! SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__")
! SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__")
! SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__")
! SLOT1BIN(slot_nb_divide, nb_divide, "__div__", "__rdiv__")
! SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__")
! SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__")
! 
! staticforward PyObject *slot_nb_power(PyObject *, PyObject *, PyObject *);
! 
! SLOT1BINFULL(slot_nb_power_binary, slot_nb_power,
! 	     nb_power, "__pow__", "__rpow__")
  
+ static PyObject *
+ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
+ {
+ 	if (modulus == Py_None)
+ 		return slot_nb_power_binary(self, other);
+ 	/* Three-arg power doesn't use __rpow__ */
+ 	return PyObject_CallMethod(self, "__pow__", "OO", other, modulus);
+ }
+ 
+ SLOT0(slot_nb_negative, "__neg__")
+ SLOT0(slot_nb_positive, "__pos__")
+ SLOT0(slot_nb_absolute, "__abs__")
+ 
  static int
  slot_nb_nonzero(PyObject *self)
***************
*** 2142,2168 ****
  }
  
! SLOT0(nb_invert, invert)
! SLOT1(nb_lshift, lshift, PyObject *, O)
! SLOT1(nb_rshift, rshift, PyObject *, O)
! SLOT1(nb_and, and, PyObject *, O)
! SLOT1(nb_xor, xor, PyObject *, O)
! SLOT1(nb_or, or, PyObject *, O)
  /* Not coerce() */
! SLOT0(nb_int, int)
! SLOT0(nb_long, long)
! SLOT0(nb_float, float)
! SLOT0(nb_oct, oct)
! SLOT0(nb_hex, hex)
! SLOT1(nb_inplace_add, iadd, PyObject *, O)
! SLOT1(nb_inplace_subtract, isub, PyObject *, O)
! SLOT1(nb_inplace_multiply, imul, PyObject *, O)
! SLOT1(nb_inplace_divide, idiv, PyObject *, O)
! SLOT1(nb_inplace_remainder, imod, PyObject *, O)
! SLOT2(nb_inplace_power, ipow, PyObject *, PyObject *, OO)
! SLOT1(nb_inplace_lshift, ilshift, PyObject *, O)
! SLOT1(nb_inplace_rshift, irshift, PyObject *, O)
! SLOT1(nb_inplace_and, iand, PyObject *, O)
! SLOT1(nb_inplace_xor, ixor, PyObject *, O)
! SLOT1(nb_inplace_or, ior, PyObject *, O)
  
  static int
--- 2194,2225 ----
  }
  
! SLOT0(slot_nb_invert, "__invert__")
! SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
! SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__")
! SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__")
! SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__")
! SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__")
  /* Not coerce() */
! SLOT0(slot_nb_int, "__int__")
! SLOT0(slot_nb_long, "__long__")
! SLOT0(slot_nb_float, "__float__")
! SLOT0(slot_nb_oct, "__oct__")
! SLOT0(slot_nb_hex, "__hex__")
! SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")
! SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")
! SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O")
! SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject *, "O")
! SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O")
! SLOT2(slot_nb_inplace_power, "__ipow__", PyObject *, PyObject *, "OO")
! SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O")
! SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O")
! SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O")
! SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *, "O")
! SLOT1(slot_nb_inplace_or, "__ior__", PyObject *, "O")
! SLOT1BIN(slot_nb_floor_divide, nb_floor_divide,
! 	 "__floordiv__", "__rfloordiv__")
! SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__")
! SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *, "O")
! SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O")
  
  static int
***************
*** 2179,2183 ****
  }
  
! SLOT0(tp_repr, repr)
  
  static long
--- 2236,2240 ----
  }
  
! SLOT0(slot_tp_repr, "__repr__")
  
  static long
***************
*** 2208,2212 ****
  }
  
! SLOT0(tp_str, str)
  
  static PyObject *
--- 2265,2269 ----
  }
  
! SLOT0(slot_tp_str, "__str__")
  
  static PyObject *
***************
*** 2272,2276 ****
  }
  
! SLOT0(tp_iter, iter)
  
  static PyObject *
--- 2329,2333 ----
  }
  
! SLOT0(slot_tp_iter, "__iter__")
  
  static PyObject *
***************
*** 2280,2284 ****
  }
  
! SLOT2(tp_descr_get, get, PyObject *, PyObject *, OO)
  
  static int
--- 2337,2341 ----
  }
  
! SLOT2(slot_tp_descr_get, "__get__", PyObject *, PyObject *, "OO")
  
  static int
***************
*** 2358,2433 ****
  	PyNumberMethods *nb = type->tp_as_number;
  
! #define SQSLOT(OPNAME, SLOTNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		sq->SLOTNAME = slot_##SLOTNAME; \
  	}
  
! #define MPSLOT(OPNAME, SLOTNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		mp->SLOTNAME = slot_##SLOTNAME; \
  	}
  
! #define NBSLOT(OPNAME, SLOTNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		nb->SLOTNAME = slot_##SLOTNAME; \
  	}
  
! #define TPSLOT(OPNAME, SLOTNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		type->SLOTNAME = slot_##SLOTNAME; \
  	}
  
! 	SQSLOT("__len__", sq_length);
! 	SQSLOT("__add__", sq_concat);
! 	SQSLOT("__mul__", sq_repeat);
! 	SQSLOT("__getitem__", sq_item);
! 	SQSLOT("__getslice__", sq_slice);
! 	SQSLOT("__setitem__", sq_ass_item);
! 	SQSLOT("__delitem__", sq_ass_item);
! 	SQSLOT("__setslice__", sq_ass_slice);
! 	SQSLOT("__delslice__", sq_ass_slice);
! 	SQSLOT("__contains__", sq_contains);
! 	SQSLOT("__iadd__", sq_inplace_concat);
! 	SQSLOT("__imul__", sq_inplace_repeat);
  
! 	MPSLOT("__len__", mp_length);
! 	MPSLOT("__getitem__", mp_subscript);
! 	MPSLOT("__setitem__", mp_ass_subscript);
! 	MPSLOT("__delitem__", mp_ass_subscript);
  
! 	NBSLOT("__add__", nb_add);
! 	NBSLOT("__sub__", nb_subtract);
! 	NBSLOT("__mul__", nb_multiply);
! 	NBSLOT("__div__", nb_divide);
! 	NBSLOT("__mod__", nb_remainder);
! 	NBSLOT("__divmod__", nb_divmod);
! 	NBSLOT("__pow__", nb_power);
! 	NBSLOT("__neg__", nb_negative);
! 	NBSLOT("__pos__", nb_positive);
! 	NBSLOT("__abs__", nb_absolute);
! 	NBSLOT("__nonzero__", nb_nonzero);
! 	NBSLOT("__invert__", nb_invert);
! 	NBSLOT("__lshift__", nb_lshift);
! 	NBSLOT("__rshift__", nb_rshift);
! 	NBSLOT("__and__", nb_and);
! 	NBSLOT("__xor__", nb_xor);
! 	NBSLOT("__or__", nb_or);
  	/* Not coerce() */
! 	NBSLOT("__int__", nb_int);
! 	NBSLOT("__long__", nb_long);
! 	NBSLOT("__float__", nb_float);
! 	NBSLOT("__oct__", nb_oct);
! 	NBSLOT("__hex__", nb_hex);
! 	NBSLOT("__iadd__", nb_inplace_add);
! 	NBSLOT("__isub__", nb_inplace_subtract);
! 	NBSLOT("__imul__", nb_inplace_multiply);
! 	NBSLOT("__idiv__", nb_inplace_divide);
! 	NBSLOT("__imod__", nb_inplace_remainder);
! 	NBSLOT("__ipow__", nb_inplace_power);
! 	NBSLOT("__ilshift__", nb_inplace_lshift);
! 	NBSLOT("__irshift__", nb_inplace_rshift);
! 	NBSLOT("__iand__", nb_inplace_and);
! 	NBSLOT("__ixor__", nb_inplace_xor);
! 	NBSLOT("__ior__", nb_inplace_or);
  
  	if (PyDict_GetItemString(dict, "__str__") ||
--- 2415,2496 ----
  	PyNumberMethods *nb = type->tp_as_number;
  
! #define SQSLOT(OPNAME, SLOTNAME, FUNCNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		sq->SLOTNAME = FUNCNAME; \
  	}
  
! #define MPSLOT(OPNAME, SLOTNAME, FUNCNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		mp->SLOTNAME = FUNCNAME; \
  	}
  
! #define NBSLOT(OPNAME, SLOTNAME, FUNCNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		nb->SLOTNAME = FUNCNAME; \
  	}
  
! #define TPSLOT(OPNAME, SLOTNAME, FUNCNAME) \
  	if (PyDict_GetItemString(dict, OPNAME)) { \
! 		type->SLOTNAME = FUNCNAME; \
  	}
  
! 	SQSLOT("__len__", sq_length, slot_sq_length);
! 	SQSLOT("__add__", sq_concat, slot_sq_concat);
! 	SQSLOT("__mul__", sq_repeat, slot_sq_repeat);
! 	SQSLOT("__getitem__", sq_item, slot_sq_item);
! 	SQSLOT("__getslice__", sq_slice, slot_sq_slice);
! 	SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item);
! 	SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item);
! 	SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice);
! 	SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice);
! 	SQSLOT("__contains__", sq_contains, slot_sq_contains);
! 	SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat);
! 	SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat);
  
! 	MPSLOT("__len__", mp_length, slot_mp_length);
! 	MPSLOT("__getitem__", mp_subscript, slot_mp_subscript);
! 	MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript);
! 	MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript);
  
! 	NBSLOT("__add__", nb_add, slot_nb_add);
! 	NBSLOT("__sub__", nb_subtract, slot_nb_subtract);
! 	NBSLOT("__mul__", nb_multiply, slot_nb_multiply);
! 	NBSLOT("__div__", nb_divide, slot_nb_divide);
! 	NBSLOT("__mod__", nb_remainder, slot_nb_remainder);
! 	NBSLOT("__divmod__", nb_divmod, slot_nb_divmod);
! 	NBSLOT("__pow__", nb_power, slot_nb_power);
! 	NBSLOT("__neg__", nb_negative, slot_nb_negative);
! 	NBSLOT("__pos__", nb_positive, slot_nb_positive);
! 	NBSLOT("__abs__", nb_absolute, slot_nb_absolute);
! 	NBSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero);
! 	NBSLOT("__invert__", nb_invert, slot_nb_invert);
! 	NBSLOT("__lshift__", nb_lshift, slot_nb_lshift);
! 	NBSLOT("__rshift__", nb_rshift, slot_nb_rshift);
! 	NBSLOT("__and__", nb_and, slot_nb_and);
! 	NBSLOT("__xor__", nb_xor, slot_nb_xor);
! 	NBSLOT("__or__", nb_or, slot_nb_or);
  	/* Not coerce() */
! 	NBSLOT("__int__", nb_int, slot_nb_int);
! 	NBSLOT("__long__", nb_long, slot_nb_long);
! 	NBSLOT("__float__", nb_float, slot_nb_float);
! 	NBSLOT("__oct__", nb_oct, slot_nb_oct);
! 	NBSLOT("__hex__", nb_hex, slot_nb_hex);
! 	NBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add);
! 	NBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract);
! 	NBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply);
! 	NBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide);
! 	NBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder);
! 	NBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power);
! 	NBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift);
! 	NBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift);
! 	NBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and);
! 	NBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor);
! 	NBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or);
! 	NBSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide);
! 	NBSLOT("__truediv__", nb_true_divide, slot_nb_true_divide);
! 	NBSLOT("__ifloordiv__", nb_inplace_floor_divide,
! 	       slot_nb_inplace_floor_divide);
! 	NBSLOT("__itruediv__", nb_inplace_true_divide,
! 	       slot_nb_inplace_true_divide);
  
  	if (PyDict_GetItemString(dict, "__str__") ||
***************
*** 2435,2456 ****
  		type->tp_print = NULL;
  
! 	TPSLOT("__cmp__", tp_compare);
! 	TPSLOT("__repr__", tp_repr);
! 	TPSLOT("__hash__", tp_hash);
! 	TPSLOT("__call__", tp_call);
! 	TPSLOT("__str__", tp_str);
! 	TPSLOT("__getattr__", tp_getattro);
! 	TPSLOT("__setattr__", tp_setattro);
! 	TPSLOT("__lt__", tp_richcompare);
! 	TPSLOT("__le__", tp_richcompare);
! 	TPSLOT("__eq__", tp_richcompare);
! 	TPSLOT("__ne__", tp_richcompare);
! 	TPSLOT("__gt__", tp_richcompare);
! 	TPSLOT("__ge__", tp_richcompare);
! 	TPSLOT("__iter__", tp_iter);
! 	TPSLOT("next", tp_iternext);
! 	TPSLOT("__get__", tp_descr_get);
! 	TPSLOT("__set__", tp_descr_set);
! 	TPSLOT("__init__", tp_init);
! 	TPSLOT("__new__", tp_new);
  }
--- 2498,2519 ----
  		type->tp_print = NULL;
  
! 	TPSLOT("__cmp__", tp_compare, slot_tp_compare);
! 	TPSLOT("__repr__", tp_repr, slot_tp_repr);
! 	TPSLOT("__hash__", tp_hash, slot_tp_hash);
! 	TPSLOT("__call__", tp_call, slot_tp_call);
! 	TPSLOT("__str__", tp_str, slot_tp_str);
! 	TPSLOT("__getattr__", tp_getattro, slot_tp_getattro);
! 	TPSLOT("__setattr__", tp_setattro, slot_tp_setattro);
! 	TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare);
! 	TPSLOT("__le__", tp_richcompare, slot_tp_richcompare);
! 	TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare);
! 	TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare);
! 	TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare);
! 	TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare);
! 	TPSLOT("__iter__", tp_iter, slot_tp_iter);
! 	TPSLOT("next", tp_iternext, slot_tp_iternext);
! 	TPSLOT("__get__", tp_descr_get, slot_tp_descr_get);
! 	TPSLOT("__set__", tp_descr_set, slot_tp_descr_set);
! 	TPSLOT("__init__", tp_init, slot_tp_init);
! 	TPSLOT("__new__", tp_new, slot_tp_new);
  }