(original) (raw)

On Tue, Nov 28, 2017 at 12:56 PM, Eric V. Smith <eric@trueblade.com> wrote:
On 11/28/2017 1:57 PM, Guido van Rossum wrote:
I would also be happy with a retreat, where we define \`\_\_eq\_\_\` to insist that the classes are the same, and people can override this to their hearts' content.

I agree. And I guess we could always add it later, if there's a huge demand and someone writes a decent implementation. There would be a slight backwards incompatibility, though. Frankly, I think it would never be needed.

One question remains: do we do what attrs does: for \`\_\_eq\_\_\` and \`\_\_ne\_\_\` use an exact type match, and for the 4 ordered comparison operators use an isinstance check? On the comparison operators, they also ignore attributes defined on any derived class \[0\]. As I said, I couldn't find an attrs issue that discusses their choice. I'll ask Hynek over on the dataclasses github issue.

Currently the dataclasses code on master uses an exact type match for all 6 methods.

Eric.

\[0\] That is, they do the following (using dataclasses terms):

Given:

@dataclass
class B:
i: int
j: int

@dataclass
class C:
k: int

Then B.\_\_eq\_\_ is:

def \_\_eq\_\_(self, other):
if other.\_\_class\_\_ is self.\_\_class\_\_:
return (other.i, other.j) == (self.i, self.j)
return NotImplemented

And B.\_\_lt\_\_ is:

def \_\_lt\_\_(self, other):
if isinstance(other, self.\_\_class\_\_):
return (other.i, other.j) < (self.i, self.j)
return NotImplemented

So if you do:
b = B(1, 2)
c = C(1, 2, 3)

Then \`B(1, 2) < C(1, 2, 3)\` ignores \`c.k\`.

Hm. Maybe for the ordering comparisons we could defer to the class with the longest list of fields, as long as there's a subtype relationship? That way bb would be equivalent, and both would use C.\_\_gt\_\_. Which had better not reject this on the basis that other is not an instance of a subclass of C.

IIRC there's already something in the interpreter that tries the most derived class first for binary operators -- that may force our hand here.

--
--Guido van Rossum (python.org/\~guido)