I’m having trouble trying to implement __eq__ for a Rect class I wrote as a C extension. I tried defining a method called __eq__, but Python seems to override it.
static PyObject *
Rect___eq__(Rect *self, PyObject *other)
{
Rect *rect = (Rect *) other;
if (self->x != rect->x || self->y != rect->y ||
self->width != rect->width || self->height != rect->height) {
Py_RETURN_FALSE;
} else {
Py_RETURN_TRUE;
}
}
static PyMethodDef Rect_methods[] = {
{"__eq__", (PyCFunction)Rect___eq__, METH_VARARGS,
"Compare Rects" },
{NULL} /* Sentinel */
};
It seems no matter what I do, Python defaults to “is” behavior:
>>> a = Rect(1, 2, 3, 4)
>>> b = Rect(1, 2, 3, 4)
>>> a == b
False
>>> a == a
True
When working with new types defined in C, you need to define tp_richcompare. Below is an implementation of rich compare for a type that always compares larger than all other types (except itself):
If you are using Python 3.x, you add it to the type object like this:
If you are using Python 2.x, there is an extra step involved. Rich comparisons were added during the lifetime of Python 2.x and for a few versions of Python, a C extension could optionally define tp_richcomare. To inform Python 2.x that your type implements rich comparisons, you need to modify tp_flags by or-ing in Py_TPFLAGS_HAVE_RICHCOMPARE.