repr, str, and eq Together

class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __repr__(self):
        return f"Point({self.x!r}, {self.y!r})"

    def __eq__(self, other):
        return isinstance(other, Point) and (self.x, self.y) == (other.x, other.y)

p1 = Point(1, 2)
p2 = Point(1, 2)

Select all statements that are true about this code.

A

hash(p1) works and returns a value derived from (x, y), because defining eq automatically derives a matching hash from the compared fields

B

print(p1) outputs Point(1, 2), because print() calls str(p1), and str() falls back to repr when a class defines no str of its own

C

p1 == p2 evaluates to True, because eq compares the (x, y) values instead of falling back to the default identity comparison

D

If Point defined only str (no repr) instead, repr(p1) would use that str implementation, since Python always prefers whichever of the two is defined