[New-bugs-announce] [issue6431] Fraction fails equality test with a user-defined type

Case Van Horsen report at bugs.python.org
Tue Jul 7 07:41:36 CEST 2009

New submission from Case Van Horsen <casevh at gmail.com>:

I've ported the GMPY module to Python 3 and found a problem comparing
Fraction to gmpy.mpq. mpq is the rational type in gmpy and knows how to
convert a Fraction into an mpq. All operations appear to work properly
except "Fraction == mpq".

"mpq == Fraction" does work correctly. gmpy's rich comparison routine
recognizes the other argument as Fraction and converts to an mpq value
properly. However, when "Fraction == mpq" is done, the Fraction argument
is converted to a float before gmpy's rich comparison is called.

The __eq__ routine in fractions.py is:

    def __eq__(a, b):
        """a == b"""
        if isinstance(b, numbers.Rational):
            return (a._numerator == b.numerator and
                    a._denominator == b.denominator)
        if isinstance(b, numbers.Complex) and b.imag == 0:
            b = b.real
        if isinstance(b, float):
            return a == a.from_float(b)
            # XXX: If b.__eq__ is implemented like this method, it may
            # give the wrong answer after float(a) changes a's
            # value. Better ways of doing this are welcome.
            return float(a) == b

Shouldn't __eq__ return NotImplemented if it doesn't know how to handle
the other argument? I changed "return float(a) == b" to "return
NotImplemented" and GMPY and Python's test suite passed all tests.

I used the same logic for comparisons between gmpy.mpf and Decimal and
they all work correctly. Decimal does return NotImplemented when it
can't convert the other argument.

(GMPY 1.10 alpha2 fails due to this issue.)

components: Library (Lib)
messages: 90211
nosy: casevh
severity: normal
status: open
title: Fraction fails equality test with a user-defined type
type: behavior
versions: Python 3.1

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list