dependencies on subclassing Extensiontypes: tp_richcompare <--> tp_hash

Uwe Hoffmann qual at tiscali.de
Wed Feb 1 17:04:04 EST 2006


Hi,

i have used Pyrex to build some python Extensionclasses. Now i
stumbled over the fact that if a subclass has a __hash__ method the
__richcmp__ of the base is not called.

# pseudocode

class Base:
	def __richcmp__():
	    print 'hi'

class Immutable(Base):
         def __hash__():
	    pass

if two instances of Immutable are compared ( e.g. Immutable() ==
Immutable() ) 'hi' is not printed.

Somebody (on pyrex mailing list) showed me that the cpython has this 
feature. If you look at typeobject.c you see the following sequence:

	if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) {
		if (type->tp_compare == NULL &&
		    type->tp_richcompare == NULL &&
		    type->tp_hash == NULL)
		{
			type->tp_compare = base->tp_compare;
			type->tp_richcompare = base->tp_richcompare;
			type->tp_hash = base->tp_hash;
		}
	}

That means either all three slots are inherited or no slot at all and 
only if there is not already one slot set.
Does anybody know why there is this strict relationship between
type->tp_richcompare and type->tp_hash . I have the feeling that this
should avoid some "incompatible" changes of __hash__ or __richcmp__ in 
the subclass but I have no clear picture (subclass compares equal but 
has a different hash ? ).

regards
      Uwe



More information about the Python-list mailing list