U
Uwe Hoffmann
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
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