Skip to content

__lt__, __gt__ and others rich comparisons behave differently as for example __iadd__ #1935

@realead

Description

@realead

The following looks inconsistent:

A small reproducer with cython 0.27.1:

cdef class MutableFloat:
    cdef double x
    def __cinit__(self, x):
        self.x=x
    def __iadd__(self, MutableFloat other):
        self.x=self.x+other.x
        return self
    def __lt__(self,  MutableFloat other):
        return self.x<other.x
    def __gt__(self, MutableFloat other):
        return self.x>other.x
    def __repr__(self):
        return str(self.x)

and now:

  a,b=MutableFloat(1.0), MutableFloat(2.0)
  a+=b #a=3.0, works
  a<b  #error x unknown
  a>b #error x unknown

when we look at the cythonized functions:

static PyObject *__pyx_pf_7mutable_12MutableFloat_2__iadd__(struct __pyx_obj_7mutable_MutableFloat *__pyx_v_self, struct __pyx_obj_7mutable_MutableFloat *__pyx_v_other); /* proto */
static PyObject *__pyx_pf_7mutable_12MutableFloat_4__lt__(PyObject *__pyx_v_self, struct __pyx_obj_7mutable_MutableFloat *__pyx_v_other); /* proto */
static PyObject *__pyx_pf_7mutable_12MutableFloat_6__gt__(PyObject *__pyx_v_self, struct __pyx_obj_7mutable_MutableFloat *__pyx_v_other); /* proto */

for __iadd__ (and any other functions) self is xxx_MutableFloat but for rich comparisons PyObject *. Maybe this is how it should be, but I didn't find anything about this potential problem in the documentation. Anyway if this is "functioning as designed", the need to declare def __gt__(MutableFloat self, MutableFloat other): looks strange to me.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions