gh-82017: Support as_integer_ratio() in the Fraction constructor (GH-120271)

Any objects that have the as_integer_ratio() method (e.g. numpy.float128)
can now be converted to a fraction.
This commit is contained in:
Serhiy Storchaka 2024-07-19 08:06:53 +03:00 committed by GitHub
parent eaf094c09b
commit c8d2630995
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 66 additions and 13 deletions

View file

@ -354,6 +354,41 @@ class FractionTest(unittest.TestCase):
self.assertRaises(OverflowError, F, Decimal('inf'))
self.assertRaises(OverflowError, F, Decimal('-inf'))
def testInitFromIntegerRatio(self):
class Ratio:
def __init__(self, ratio):
self._ratio = ratio
def as_integer_ratio(self):
return self._ratio
self.assertEqual((7, 3), _components(F(Ratio((7, 3)))))
errmsg = "argument should be a string or a number"
# the type also has an "as_integer_ratio" attribute.
self.assertRaisesRegex(TypeError, errmsg, F, Ratio)
# bad ratio
self.assertRaises(TypeError, F, Ratio(7))
self.assertRaises(ValueError, F, Ratio((7,)))
self.assertRaises(ValueError, F, Ratio((7, 3, 1)))
# only single-argument form
self.assertRaises(TypeError, F, Ratio((3, 7)), 11)
self.assertRaises(TypeError, F, 2, Ratio((-10, 9)))
# as_integer_ratio not defined in a class
class A:
pass
a = A()
a.as_integer_ratio = lambda: (9, 5)
self.assertEqual((9, 5), _components(F(a)))
# as_integer_ratio defined in a metaclass
class M(type):
def as_integer_ratio(self):
return (11, 9)
class B(metaclass=M):
pass
self.assertRaisesRegex(TypeError, errmsg, F, B)
self.assertRaisesRegex(TypeError, errmsg, F, B())
def testFromString(self):
self.assertEqual((5, 1), _components(F("5")))
self.assertEqual((3, 2), _components(F("3/2")))