bpo-44547: Make Fractions objects instances of typing.SupportsInt (GH-27851)

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
This commit is contained in:
Mark Dickinson 2021-10-21 23:09:47 +01:00 committed by GitHub
parent 51375388be
commit d1b24775b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 3 deletions

View file

@ -8,6 +8,7 @@ import operator
import fractions
import functools
import sys
import typing
import unittest
from copy import copy, deepcopy
import pickle
@ -385,6 +386,47 @@ class FractionTest(unittest.TestCase):
self.assertTypedEquals(0.1+0j, complex(F(1,10)))
def testSupportsInt(self):
# See bpo-44547.
f = F(3, 2)
self.assertIsInstance(f, typing.SupportsInt)
self.assertEqual(int(f), 1)
self.assertEqual(type(int(f)), int)
def testIntGuaranteesIntReturn(self):
# Check that int(some_fraction) gives a result of exact type `int`
# even if the fraction is using some other Integral type for its
# numerator and denominator.
class CustomInt(int):
"""
Subclass of int with just enough machinery to convince the Fraction
constructor to produce something with CustomInt numerator and
denominator.
"""
@property
def numerator(self):
return self
@property
def denominator(self):
return CustomInt(1)
def __mul__(self, other):
return CustomInt(int(self) * int(other))
def __floordiv__(self, other):
return CustomInt(int(self) // int(other))
f = F(CustomInt(13), CustomInt(5))
self.assertIsInstance(f.numerator, CustomInt)
self.assertIsInstance(f.denominator, CustomInt)
self.assertIsInstance(f, typing.SupportsInt)
self.assertEqual(int(f), 2)
self.assertEqual(type(int(f)), int)
def testBoolGuarateesBoolReturn(self):
# Ensure that __bool__ is used on numerator which guarantees a bool
# return. See also bpo-39274.