(root)/
Python-3.11.7/
Lib/
test/
test_fractions.py
       1  """Tests for Lib/fractions.py."""
       2  
       3  from decimal import Decimal
       4  from test.support import requires_IEEE_754
       5  import math
       6  import numbers
       7  import operator
       8  import fractions
       9  import functools
      10  import sys
      11  import typing
      12  import unittest
      13  from copy import copy, deepcopy
      14  import pickle
      15  from pickle import dumps, loads
      16  F = fractions.Fraction
      17  
      18  
      19  class ESC[4;38;5;81mDummyFloat(ESC[4;38;5;149mobject):
      20      """Dummy float class for testing comparisons with Fractions"""
      21  
      22      def __init__(self, value):
      23          if not isinstance(value, float):
      24              raise TypeError("DummyFloat can only be initialized from float")
      25          self.value = value
      26  
      27      def _richcmp(self, other, op):
      28          if isinstance(other, numbers.Rational):
      29              return op(F.from_float(self.value), other)
      30          elif isinstance(other, DummyFloat):
      31              return op(self.value, other.value)
      32          else:
      33              return NotImplemented
      34  
      35      def __eq__(self, other): return self._richcmp(other, operator.eq)
      36      def __le__(self, other): return self._richcmp(other, operator.le)
      37      def __lt__(self, other): return self._richcmp(other, operator.lt)
      38      def __ge__(self, other): return self._richcmp(other, operator.ge)
      39      def __gt__(self, other): return self._richcmp(other, operator.gt)
      40  
      41      # shouldn't be calling __float__ at all when doing comparisons
      42      def __float__(self):
      43          assert False, "__float__ should not be invoked for comparisons"
      44  
      45      # same goes for subtraction
      46      def __sub__(self, other):
      47          assert False, "__sub__ should not be invoked for comparisons"
      48      __rsub__ = __sub__
      49  
      50  
      51  class ESC[4;38;5;81mDummyRational(ESC[4;38;5;149mobject):
      52      """Test comparison of Fraction with a naive rational implementation."""
      53  
      54      def __init__(self, num, den):
      55          g = math.gcd(num, den)
      56          self.num = num // g
      57          self.den = den // g
      58  
      59      def __eq__(self, other):
      60          if isinstance(other, fractions.Fraction):
      61              return (self.num == other._numerator and
      62                      self.den == other._denominator)
      63          else:
      64              return NotImplemented
      65  
      66      def __lt__(self, other):
      67          return(self.num * other._denominator < self.den * other._numerator)
      68  
      69      def __gt__(self, other):
      70          return(self.num * other._denominator > self.den * other._numerator)
      71  
      72      def __le__(self, other):
      73          return(self.num * other._denominator <= self.den * other._numerator)
      74  
      75      def __ge__(self, other):
      76          return(self.num * other._denominator >= self.den * other._numerator)
      77  
      78      # this class is for testing comparisons; conversion to float
      79      # should never be used for a comparison, since it loses accuracy
      80      def __float__(self):
      81          assert False, "__float__ should not be invoked"
      82  
      83  class ESC[4;38;5;81mDummyFraction(ESC[4;38;5;149mfractionsESC[4;38;5;149m.ESC[4;38;5;149mFraction):
      84      """Dummy Fraction subclass for copy and deepcopy testing."""
      85  
      86  
      87  def _components(r):
      88      return (r.numerator, r.denominator)
      89  
      90  
      91  class ESC[4;38;5;81mFractionTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      92  
      93      def assertTypedEquals(self, expected, actual):
      94          """Asserts that both the types and values are the same."""
      95          self.assertEqual(type(expected), type(actual))
      96          self.assertEqual(expected, actual)
      97  
      98      def assertTypedTupleEquals(self, expected, actual):
      99          """Asserts that both the types and values in the tuples are the same."""
     100          self.assertTupleEqual(expected, actual)
     101          self.assertListEqual(list(map(type, expected)), list(map(type, actual)))
     102  
     103      def assertRaisesMessage(self, exc_type, message,
     104                              callable, *args, **kwargs):
     105          """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
     106          try:
     107              callable(*args, **kwargs)
     108          except exc_type as e:
     109              self.assertEqual(message, str(e))
     110          else:
     111              self.fail("%s not raised" % exc_type.__name__)
     112  
     113      def testInit(self):
     114          self.assertEqual((0, 1), _components(F()))
     115          self.assertEqual((7, 1), _components(F(7)))
     116          self.assertEqual((7, 3), _components(F(F(7, 3))))
     117  
     118          self.assertEqual((-1, 1), _components(F(-1, 1)))
     119          self.assertEqual((-1, 1), _components(F(1, -1)))
     120          self.assertEqual((1, 1), _components(F(-2, -2)))
     121          self.assertEqual((1, 2), _components(F(5, 10)))
     122          self.assertEqual((7, 15), _components(F(7, 15)))
     123          self.assertEqual((10**23, 1), _components(F(10**23)))
     124  
     125          self.assertEqual((3, 77), _components(F(F(3, 7), 11)))
     126          self.assertEqual((-9, 5), _components(F(2, F(-10, 9))))
     127          self.assertEqual((2486, 2485), _components(F(F(22, 7), F(355, 113))))
     128  
     129          self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
     130                                   F, 12, 0)
     131          self.assertRaises(TypeError, F, 1.5 + 3j)
     132  
     133          self.assertRaises(TypeError, F, "3/2", 3)
     134          self.assertRaises(TypeError, F, 3, 0j)
     135          self.assertRaises(TypeError, F, 3, 1j)
     136          self.assertRaises(TypeError, F, 1, 2, 3)
     137  
     138      @requires_IEEE_754
     139      def testInitFromFloat(self):
     140          self.assertEqual((5, 2), _components(F(2.5)))
     141          self.assertEqual((0, 1), _components(F(-0.0)))
     142          self.assertEqual((3602879701896397, 36028797018963968),
     143                           _components(F(0.1)))
     144          # bug 16469: error types should be consistent with float -> int
     145          self.assertRaises(ValueError, F, float('nan'))
     146          self.assertRaises(OverflowError, F, float('inf'))
     147          self.assertRaises(OverflowError, F, float('-inf'))
     148  
     149      def testInitFromDecimal(self):
     150          self.assertEqual((11, 10),
     151                           _components(F(Decimal('1.1'))))
     152          self.assertEqual((7, 200),
     153                           _components(F(Decimal('3.5e-2'))))
     154          self.assertEqual((0, 1),
     155                           _components(F(Decimal('.000e20'))))
     156          # bug 16469: error types should be consistent with decimal -> int
     157          self.assertRaises(ValueError, F, Decimal('nan'))
     158          self.assertRaises(ValueError, F, Decimal('snan'))
     159          self.assertRaises(OverflowError, F, Decimal('inf'))
     160          self.assertRaises(OverflowError, F, Decimal('-inf'))
     161  
     162      def testFromString(self):
     163          self.assertEqual((5, 1), _components(F("5")))
     164          self.assertEqual((3, 2), _components(F("3/2")))
     165          self.assertEqual((3, 2), _components(F(" \n  +3/2")))
     166          self.assertEqual((-3, 2), _components(F("-3/2  ")))
     167          self.assertEqual((13, 2), _components(F("    013/02 \n  ")))
     168          self.assertEqual((16, 5), _components(F(" 3.2 ")))
     169          self.assertEqual((-16, 5), _components(F(" -3.2 ")))
     170          self.assertEqual((-3, 1), _components(F(" -3. ")))
     171          self.assertEqual((3, 5), _components(F(" .6 ")))
     172          self.assertEqual((1, 3125), _components(F("32.e-5")))
     173          self.assertEqual((1000000, 1), _components(F("1E+06")))
     174          self.assertEqual((-12300, 1), _components(F("-1.23e4")))
     175          self.assertEqual((0, 1), _components(F(" .0e+0\t")))
     176          self.assertEqual((0, 1), _components(F("-0.000e0")))
     177          self.assertEqual((123, 1), _components(F("1_2_3")))
     178          self.assertEqual((41, 107), _components(F("1_2_3/3_2_1")))
     179          self.assertEqual((6283, 2000), _components(F("3.14_15")))
     180          self.assertEqual((6283, 2*10**13), _components(F("3.14_15e-1_0")))
     181          self.assertEqual((101, 100), _components(F("1.01")))
     182          self.assertEqual((101, 100), _components(F("1.0_1")))
     183  
     184          self.assertRaisesMessage(
     185              ZeroDivisionError, "Fraction(3, 0)",
     186              F, "3/0")
     187          self.assertRaisesMessage(
     188              ValueError, "Invalid literal for Fraction: '3/'",
     189              F, "3/")
     190          self.assertRaisesMessage(
     191              ValueError, "Invalid literal for Fraction: '/2'",
     192              F, "/2")
     193          self.assertRaisesMessage(
     194              ValueError, "Invalid literal for Fraction: '3 /2'",
     195              F, "3 /2")
     196          self.assertRaisesMessage(
     197              # Denominators don't need a sign.
     198              ValueError, "Invalid literal for Fraction: '3/+2'",
     199              F, "3/+2")
     200          self.assertRaisesMessage(
     201              # Imitate float's parsing.
     202              ValueError, "Invalid literal for Fraction: '+ 3/2'",
     203              F, "+ 3/2")
     204          self.assertRaisesMessage(
     205              # Avoid treating '.' as a regex special character.
     206              ValueError, "Invalid literal for Fraction: '3a2'",
     207              F, "3a2")
     208          self.assertRaisesMessage(
     209              # Don't accept combinations of decimals and rationals.
     210              ValueError, "Invalid literal for Fraction: '3/7.2'",
     211              F, "3/7.2")
     212          self.assertRaisesMessage(
     213              # Don't accept combinations of decimals and rationals.
     214              ValueError, "Invalid literal for Fraction: '3.2/7'",
     215              F, "3.2/7")
     216          self.assertRaisesMessage(
     217              # Allow 3. and .3, but not .
     218              ValueError, "Invalid literal for Fraction: '.'",
     219              F, ".")
     220          self.assertRaisesMessage(
     221              ValueError, "Invalid literal for Fraction: '_'",
     222              F, "_")
     223          self.assertRaisesMessage(
     224              ValueError, "Invalid literal for Fraction: '_1'",
     225              F, "_1")
     226          self.assertRaisesMessage(
     227              ValueError, "Invalid literal for Fraction: '1__2'",
     228              F, "1__2")
     229          self.assertRaisesMessage(
     230              ValueError, "Invalid literal for Fraction: '/_'",
     231              F, "/_")
     232          self.assertRaisesMessage(
     233              ValueError, "Invalid literal for Fraction: '1_/'",
     234              F, "1_/")
     235          self.assertRaisesMessage(
     236              ValueError, "Invalid literal for Fraction: '_1/'",
     237              F, "_1/")
     238          self.assertRaisesMessage(
     239              ValueError, "Invalid literal for Fraction: '1__2/'",
     240              F, "1__2/")
     241          self.assertRaisesMessage(
     242              ValueError, "Invalid literal for Fraction: '1/_'",
     243              F, "1/_")
     244          self.assertRaisesMessage(
     245              ValueError, "Invalid literal for Fraction: '1/_1'",
     246              F, "1/_1")
     247          self.assertRaisesMessage(
     248              ValueError, "Invalid literal for Fraction: '1/1__2'",
     249              F, "1/1__2")
     250          self.assertRaisesMessage(
     251              ValueError, "Invalid literal for Fraction: '1._111'",
     252              F, "1._111")
     253          self.assertRaisesMessage(
     254              ValueError, "Invalid literal for Fraction: '1.1__1'",
     255              F, "1.1__1")
     256          self.assertRaisesMessage(
     257              ValueError, "Invalid literal for Fraction: '1.1e+_1'",
     258              F, "1.1e+_1")
     259          self.assertRaisesMessage(
     260              ValueError, "Invalid literal for Fraction: '1.1e+1__1'",
     261              F, "1.1e+1__1")
     262          # Test catastrophic backtracking.
     263          val = "9"*50 + "_"
     264          self.assertRaisesMessage(
     265              ValueError, "Invalid literal for Fraction: '" + val + "'",
     266              F, val)
     267          self.assertRaisesMessage(
     268              ValueError, "Invalid literal for Fraction: '1/" + val + "'",
     269              F, "1/" + val)
     270          self.assertRaisesMessage(
     271              ValueError, "Invalid literal for Fraction: '1." + val + "'",
     272              F, "1." + val)
     273          self.assertRaisesMessage(
     274              ValueError, "Invalid literal for Fraction: '1.1+e" + val + "'",
     275              F, "1.1+e" + val)
     276  
     277      def testImmutable(self):
     278          r = F(7, 3)
     279          r.__init__(2, 15)
     280          self.assertEqual((7, 3), _components(r))
     281  
     282          self.assertRaises(AttributeError, setattr, r, 'numerator', 12)
     283          self.assertRaises(AttributeError, setattr, r, 'denominator', 6)
     284          self.assertEqual((7, 3), _components(r))
     285  
     286          # But if you _really_ need to:
     287          r._numerator = 4
     288          r._denominator = 2
     289          self.assertEqual((4, 2), _components(r))
     290          # Which breaks some important operations:
     291          self.assertNotEqual(F(4, 2), r)
     292  
     293      def testFromFloat(self):
     294          self.assertRaises(TypeError, F.from_float, 3+4j)
     295          self.assertEqual((10, 1), _components(F.from_float(10)))
     296          bigint = 1234567890123456789
     297          self.assertEqual((bigint, 1), _components(F.from_float(bigint)))
     298          self.assertEqual((0, 1), _components(F.from_float(-0.0)))
     299          self.assertEqual((10, 1), _components(F.from_float(10.0)))
     300          self.assertEqual((-5, 2), _components(F.from_float(-2.5)))
     301          self.assertEqual((99999999999999991611392, 1),
     302                           _components(F.from_float(1e23)))
     303          self.assertEqual(float(10**23), float(F.from_float(1e23)))
     304          self.assertEqual((3602879701896397, 1125899906842624),
     305                           _components(F.from_float(3.2)))
     306          self.assertEqual(3.2, float(F.from_float(3.2)))
     307  
     308          inf = 1e1000
     309          nan = inf - inf
     310          # bug 16469: error types should be consistent with float -> int
     311          self.assertRaisesMessage(
     312              OverflowError, "cannot convert Infinity to integer ratio",
     313              F.from_float, inf)
     314          self.assertRaisesMessage(
     315              OverflowError, "cannot convert Infinity to integer ratio",
     316              F.from_float, -inf)
     317          self.assertRaisesMessage(
     318              ValueError, "cannot convert NaN to integer ratio",
     319              F.from_float, nan)
     320  
     321      def testFromDecimal(self):
     322          self.assertRaises(TypeError, F.from_decimal, 3+4j)
     323          self.assertEqual(F(10, 1), F.from_decimal(10))
     324          self.assertEqual(F(0), F.from_decimal(Decimal("-0")))
     325          self.assertEqual(F(5, 10), F.from_decimal(Decimal("0.5")))
     326          self.assertEqual(F(5, 1000), F.from_decimal(Decimal("5e-3")))
     327          self.assertEqual(F(5000), F.from_decimal(Decimal("5e3")))
     328          self.assertEqual(1 - F(1, 10**30),
     329                           F.from_decimal(Decimal("0." + "9" * 30)))
     330  
     331          # bug 16469: error types should be consistent with decimal -> int
     332          self.assertRaisesMessage(
     333              OverflowError, "cannot convert Infinity to integer ratio",
     334              F.from_decimal, Decimal("inf"))
     335          self.assertRaisesMessage(
     336              OverflowError, "cannot convert Infinity to integer ratio",
     337              F.from_decimal, Decimal("-inf"))
     338          self.assertRaisesMessage(
     339              ValueError, "cannot convert NaN to integer ratio",
     340              F.from_decimal, Decimal("nan"))
     341          self.assertRaisesMessage(
     342              ValueError, "cannot convert NaN to integer ratio",
     343              F.from_decimal, Decimal("snan"))
     344  
     345      def test_as_integer_ratio(self):
     346          self.assertEqual(F(4, 6).as_integer_ratio(), (2, 3))
     347          self.assertEqual(F(-4, 6).as_integer_ratio(), (-2, 3))
     348          self.assertEqual(F(4, -6).as_integer_ratio(), (-2, 3))
     349          self.assertEqual(F(0, 6).as_integer_ratio(), (0, 1))
     350  
     351      def testLimitDenominator(self):
     352          rpi = F('3.1415926535897932')
     353          self.assertEqual(rpi.limit_denominator(10000), F(355, 113))
     354          self.assertEqual(-rpi.limit_denominator(10000), F(-355, 113))
     355          self.assertEqual(rpi.limit_denominator(113), F(355, 113))
     356          self.assertEqual(rpi.limit_denominator(112), F(333, 106))
     357          self.assertEqual(F(201, 200).limit_denominator(100), F(1))
     358          self.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
     359          self.assertEqual(F(0).limit_denominator(10000), F(0))
     360          for i in (0, -1):
     361              self.assertRaisesMessage(
     362                  ValueError, "max_denominator should be at least 1",
     363                  F(1).limit_denominator, i)
     364  
     365      def testConversions(self):
     366          self.assertTypedEquals(-1, math.trunc(F(-11, 10)))
     367          self.assertTypedEquals(1, math.trunc(F(11, 10)))
     368          self.assertTypedEquals(-2, math.floor(F(-11, 10)))
     369          self.assertTypedEquals(-1, math.ceil(F(-11, 10)))
     370          self.assertTypedEquals(-1, math.ceil(F(-10, 10)))
     371          self.assertTypedEquals(-1, int(F(-11, 10)))
     372          self.assertTypedEquals(0, round(F(-1, 10)))
     373          self.assertTypedEquals(0, round(F(-5, 10)))
     374          self.assertTypedEquals(-2, round(F(-15, 10)))
     375          self.assertTypedEquals(-1, round(F(-7, 10)))
     376  
     377          self.assertEqual(False, bool(F(0, 1)))
     378          self.assertEqual(True, bool(F(3, 2)))
     379          self.assertTypedEquals(0.1, float(F(1, 10)))
     380  
     381          # Check that __float__ isn't implemented by converting the
     382          # numerator and denominator to float before dividing.
     383          self.assertRaises(OverflowError, float, int('2'*400+'7'))
     384          self.assertAlmostEqual(2.0/3,
     385                                 float(F(int('2'*400+'7'), int('3'*400+'1'))))
     386  
     387          self.assertTypedEquals(0.1+0j, complex(F(1,10)))
     388  
     389      def testSupportsInt(self):
     390          # See bpo-44547.
     391          f = F(3, 2)
     392          self.assertIsInstance(f, typing.SupportsInt)
     393          self.assertEqual(int(f), 1)
     394          self.assertEqual(type(int(f)), int)
     395  
     396      def testIntGuaranteesIntReturn(self):
     397          # Check that int(some_fraction) gives a result of exact type `int`
     398          # even if the fraction is using some other Integral type for its
     399          # numerator and denominator.
     400  
     401          class ESC[4;38;5;81mCustomInt(ESC[4;38;5;149mint):
     402              """
     403              Subclass of int with just enough machinery to convince the Fraction
     404              constructor to produce something with CustomInt numerator and
     405              denominator.
     406              """
     407  
     408              @property
     409              def numerator(self):
     410                  return self
     411  
     412              @property
     413              def denominator(self):
     414                  return CustomInt(1)
     415  
     416              def __mul__(self, other):
     417                  return CustomInt(int(self) * int(other))
     418  
     419              def __floordiv__(self, other):
     420                  return CustomInt(int(self) // int(other))
     421  
     422          f = F(CustomInt(13), CustomInt(5))
     423  
     424          self.assertIsInstance(f.numerator, CustomInt)
     425          self.assertIsInstance(f.denominator, CustomInt)
     426          self.assertIsInstance(f, typing.SupportsInt)
     427          self.assertEqual(int(f), 2)
     428          self.assertEqual(type(int(f)), int)
     429  
     430      def testBoolGuarateesBoolReturn(self):
     431          # Ensure that __bool__ is used on numerator which guarantees a bool
     432          # return.  See also bpo-39274.
     433          @functools.total_ordering
     434          class ESC[4;38;5;81mCustomValue:
     435              denominator = 1
     436  
     437              def __init__(self, value):
     438                  self.value = value
     439  
     440              def __bool__(self):
     441                  return bool(self.value)
     442  
     443              @property
     444              def numerator(self):
     445                  # required to preserve `self` during instantiation
     446                  return self
     447  
     448              def __eq__(self, other):
     449                  raise AssertionError("Avoid comparisons in Fraction.__bool__")
     450  
     451              __lt__ = __eq__
     452  
     453          # We did not implement all abstract methods, so register:
     454          numbers.Rational.register(CustomValue)
     455  
     456          numerator = CustomValue(1)
     457          r = F(numerator)
     458          # ensure the numerator was not lost during instantiation:
     459          self.assertIs(r.numerator, numerator)
     460          self.assertIs(bool(r), True)
     461  
     462          numerator = CustomValue(0)
     463          r = F(numerator)
     464          self.assertIs(bool(r), False)
     465  
     466      def testRound(self):
     467          self.assertTypedEquals(F(-200), round(F(-150), -2))
     468          self.assertTypedEquals(F(-200), round(F(-250), -2))
     469          self.assertTypedEquals(F(30), round(F(26), -1))
     470          self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1))
     471          self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1))
     472  
     473      def testArithmetic(self):
     474          self.assertEqual(F(1, 2), F(1, 10) + F(2, 5))
     475          self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5))
     476          self.assertEqual(F(1, 25), F(1, 10) * F(2, 5))
     477          self.assertEqual(F(5, 6), F(2, 3) * F(5, 4))
     478          self.assertEqual(F(1, 4), F(1, 10) / F(2, 5))
     479          self.assertEqual(F(-15, 8), F(3, 4) / F(-2, 5))
     480          self.assertTypedEquals(2, F(9, 10) // F(2, 5))
     481          self.assertTypedEquals(10**23, F(10**23, 1) // F(1))
     482          self.assertEqual(F(5, 6), F(7, 3) % F(3, 2))
     483          self.assertEqual(F(2, 3), F(-7, 3) % F(3, 2))
     484          self.assertEqual((F(1), F(5, 6)), divmod(F(7, 3), F(3, 2)))
     485          self.assertEqual((F(-2), F(2, 3)), divmod(F(-7, 3), F(3, 2)))
     486          self.assertEqual(F(8, 27), F(2, 3) ** F(3))
     487          self.assertEqual(F(27, 8), F(2, 3) ** F(-3))
     488          self.assertTypedEquals(2.0, F(4) ** F(1, 2))
     489          self.assertEqual(F(1, 1), +F(1, 1))
     490          z = pow(F(-1), F(1, 2))
     491          self.assertAlmostEqual(z.real, 0)
     492          self.assertEqual(z.imag, 1)
     493          # Regression test for #27539.
     494          p = F(-1, 2) ** 0
     495          self.assertEqual(p, F(1, 1))
     496          self.assertEqual(p.numerator, 1)
     497          self.assertEqual(p.denominator, 1)
     498          p = F(-1, 2) ** -1
     499          self.assertEqual(p, F(-2, 1))
     500          self.assertEqual(p.numerator, -2)
     501          self.assertEqual(p.denominator, 1)
     502          p = F(-1, 2) ** -2
     503          self.assertEqual(p, F(4, 1))
     504          self.assertEqual(p.numerator, 4)
     505          self.assertEqual(p.denominator, 1)
     506  
     507      def testLargeArithmetic(self):
     508          self.assertTypedEquals(
     509              F(10101010100808080808080808101010101010000000000000000,
     510                1010101010101010101010101011111111101010101010101010101010101),
     511              F(10**35+1, 10**27+1) % F(10**27+1, 10**35-1)
     512          )
     513          self.assertTypedEquals(
     514              F(7, 1901475900342344102245054808064),
     515              F(-2**100, 3) % F(5, 2**100)
     516          )
     517          self.assertTypedTupleEquals(
     518              (9999999999999999,
     519               F(10101010100808080808080808101010101010000000000000000,
     520                 1010101010101010101010101011111111101010101010101010101010101)),
     521              divmod(F(10**35+1, 10**27+1), F(10**27+1, 10**35-1))
     522          )
     523          self.assertTypedEquals(
     524              -2 ** 200 // 15,
     525              F(-2**100, 3) // F(5, 2**100)
     526          )
     527          self.assertTypedEquals(
     528              1,
     529              F(5, 2**100) // F(3, 2**100)
     530          )
     531          self.assertTypedEquals(
     532              (1, F(2, 2**100)),
     533              divmod(F(5, 2**100), F(3, 2**100))
     534          )
     535          self.assertTypedTupleEquals(
     536              (-2 ** 200 // 15,
     537               F(7, 1901475900342344102245054808064)),
     538              divmod(F(-2**100, 3), F(5, 2**100))
     539          )
     540  
     541      def testMixedArithmetic(self):
     542          self.assertTypedEquals(F(11, 10), F(1, 10) + 1)
     543          self.assertTypedEquals(1.1, F(1, 10) + 1.0)
     544          self.assertTypedEquals(1.1 + 0j, F(1, 10) + (1.0 + 0j))
     545          self.assertTypedEquals(F(11, 10), 1 + F(1, 10))
     546          self.assertTypedEquals(1.1, 1.0 + F(1, 10))
     547          self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + F(1, 10))
     548  
     549          self.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
     550          self.assertTypedEquals(-0.9, F(1, 10) - 1.0)
     551          self.assertTypedEquals(-0.9 + 0j, F(1, 10) - (1.0 + 0j))
     552          self.assertTypedEquals(F(9, 10), 1 - F(1, 10))
     553          self.assertTypedEquals(0.9, 1.0 - F(1, 10))
     554          self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - F(1, 10))
     555  
     556          self.assertTypedEquals(F(1, 10), F(1, 10) * 1)
     557          self.assertTypedEquals(0.1, F(1, 10) * 1.0)
     558          self.assertTypedEquals(0.1 + 0j, F(1, 10) * (1.0 + 0j))
     559          self.assertTypedEquals(F(1, 10), 1 * F(1, 10))
     560          self.assertTypedEquals(0.1, 1.0 * F(1, 10))
     561          self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * F(1, 10))
     562  
     563          self.assertTypedEquals(F(1, 10), F(1, 10) / 1)
     564          self.assertTypedEquals(0.1, F(1, 10) / 1.0)
     565          self.assertTypedEquals(0.1 + 0j, F(1, 10) / (1.0 + 0j))
     566          self.assertTypedEquals(F(10, 1), 1 / F(1, 10))
     567          self.assertTypedEquals(10.0, 1.0 / F(1, 10))
     568          self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))
     569  
     570          self.assertTypedEquals(0, F(1, 10) // 1)
     571          self.assertTypedEquals(0.0, F(1, 10) // 1.0)
     572          self.assertTypedEquals(10, 1 // F(1, 10))
     573          self.assertTypedEquals(10**23, 10**22 // F(1, 10))
     574          self.assertTypedEquals(1.0 // 0.1, 1.0 // F(1, 10))
     575  
     576          self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
     577          self.assertTypedEquals(0.1, F(1, 10) % 1.0)
     578          self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
     579          self.assertTypedEquals(1.0 % 0.1, 1.0 % F(1, 10))
     580          self.assertTypedEquals(0.1, F(1, 10) % float('inf'))
     581          self.assertTypedEquals(float('-inf'), F(1, 10) % float('-inf'))
     582          self.assertTypedEquals(float('inf'), F(-1, 10) % float('inf'))
     583          self.assertTypedEquals(-0.1, F(-1, 10) % float('-inf'))
     584  
     585          self.assertTypedTupleEquals((0, F(1, 10)), divmod(F(1, 10), 1))
     586          self.assertTypedTupleEquals(divmod(0.1, 1.0), divmod(F(1, 10), 1.0))
     587          self.assertTypedTupleEquals((10, F(0)), divmod(1, F(1, 10)))
     588          self.assertTypedTupleEquals(divmod(1.0, 0.1), divmod(1.0, F(1, 10)))
     589          self.assertTypedTupleEquals(divmod(0.1, float('inf')), divmod(F(1, 10), float('inf')))
     590          self.assertTypedTupleEquals(divmod(0.1, float('-inf')), divmod(F(1, 10), float('-inf')))
     591          self.assertTypedTupleEquals(divmod(-0.1, float('inf')), divmod(F(-1, 10), float('inf')))
     592          self.assertTypedTupleEquals(divmod(-0.1, float('-inf')), divmod(F(-1, 10), float('-inf')))
     593  
     594          # ** has more interesting conversion rules.
     595          self.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
     596          self.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
     597          self.assertTypedEquals(0.1, F(1, 10) ** 1.0)
     598          self.assertTypedEquals(0.1 + 0j, F(1, 10) ** (1.0 + 0j))
     599          self.assertTypedEquals(4 , 2 ** F(2, 1))
     600          z = pow(-1, F(1, 2))
     601          self.assertAlmostEqual(0, z.real)
     602          self.assertEqual(1, z.imag)
     603          self.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
     604          self.assertTypedEquals(2.0 , 4 ** F(1, 2))
     605          self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
     606          self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
     607          self.assertRaises(ZeroDivisionError, operator.pow,
     608                            F(0, 1), -2)
     609  
     610      def testMixingWithDecimal(self):
     611          # Decimal refuses mixed arithmetic (but not mixed comparisons)
     612          self.assertRaises(TypeError, operator.add,
     613                            F(3,11), Decimal('3.1415926'))
     614          self.assertRaises(TypeError, operator.add,
     615                            Decimal('3.1415926'), F(3,11))
     616  
     617      def testComparisons(self):
     618          self.assertTrue(F(1, 2) < F(2, 3))
     619          self.assertFalse(F(1, 2) < F(1, 2))
     620          self.assertTrue(F(1, 2) <= F(2, 3))
     621          self.assertTrue(F(1, 2) <= F(1, 2))
     622          self.assertFalse(F(2, 3) <= F(1, 2))
     623          self.assertTrue(F(1, 2) == F(1, 2))
     624          self.assertFalse(F(1, 2) == F(1, 3))
     625          self.assertFalse(F(1, 2) != F(1, 2))
     626          self.assertTrue(F(1, 2) != F(1, 3))
     627  
     628      def testComparisonsDummyRational(self):
     629          self.assertTrue(F(1, 2) == DummyRational(1, 2))
     630          self.assertTrue(DummyRational(1, 2) == F(1, 2))
     631          self.assertFalse(F(1, 2) == DummyRational(3, 4))
     632          self.assertFalse(DummyRational(3, 4) == F(1, 2))
     633  
     634          self.assertTrue(F(1, 2) < DummyRational(3, 4))
     635          self.assertFalse(F(1, 2) < DummyRational(1, 2))
     636          self.assertFalse(F(1, 2) < DummyRational(1, 7))
     637          self.assertFalse(F(1, 2) > DummyRational(3, 4))
     638          self.assertFalse(F(1, 2) > DummyRational(1, 2))
     639          self.assertTrue(F(1, 2) > DummyRational(1, 7))
     640          self.assertTrue(F(1, 2) <= DummyRational(3, 4))
     641          self.assertTrue(F(1, 2) <= DummyRational(1, 2))
     642          self.assertFalse(F(1, 2) <= DummyRational(1, 7))
     643          self.assertFalse(F(1, 2) >= DummyRational(3, 4))
     644          self.assertTrue(F(1, 2) >= DummyRational(1, 2))
     645          self.assertTrue(F(1, 2) >= DummyRational(1, 7))
     646  
     647          self.assertTrue(DummyRational(1, 2) < F(3, 4))
     648          self.assertFalse(DummyRational(1, 2) < F(1, 2))
     649          self.assertFalse(DummyRational(1, 2) < F(1, 7))
     650          self.assertFalse(DummyRational(1, 2) > F(3, 4))
     651          self.assertFalse(DummyRational(1, 2) > F(1, 2))
     652          self.assertTrue(DummyRational(1, 2) > F(1, 7))
     653          self.assertTrue(DummyRational(1, 2) <= F(3, 4))
     654          self.assertTrue(DummyRational(1, 2) <= F(1, 2))
     655          self.assertFalse(DummyRational(1, 2) <= F(1, 7))
     656          self.assertFalse(DummyRational(1, 2) >= F(3, 4))
     657          self.assertTrue(DummyRational(1, 2) >= F(1, 2))
     658          self.assertTrue(DummyRational(1, 2) >= F(1, 7))
     659  
     660      def testComparisonsDummyFloat(self):
     661          x = DummyFloat(1./3.)
     662          y = F(1, 3)
     663          self.assertTrue(x != y)
     664          self.assertTrue(x < y or x > y)
     665          self.assertFalse(x == y)
     666          self.assertFalse(x <= y and x >= y)
     667          self.assertTrue(y != x)
     668          self.assertTrue(y < x or y > x)
     669          self.assertFalse(y == x)
     670          self.assertFalse(y <= x and y >= x)
     671  
     672      def testMixedLess(self):
     673          self.assertTrue(2 < F(5, 2))
     674          self.assertFalse(2 < F(4, 2))
     675          self.assertTrue(F(5, 2) < 3)
     676          self.assertFalse(F(4, 2) < 2)
     677  
     678          self.assertTrue(F(1, 2) < 0.6)
     679          self.assertFalse(F(1, 2) < 0.4)
     680          self.assertTrue(0.4 < F(1, 2))
     681          self.assertFalse(0.5 < F(1, 2))
     682  
     683          self.assertFalse(float('inf') < F(1, 2))
     684          self.assertTrue(float('-inf') < F(0, 10))
     685          self.assertFalse(float('nan') < F(-3, 7))
     686          self.assertTrue(F(1, 2) < float('inf'))
     687          self.assertFalse(F(17, 12) < float('-inf'))
     688          self.assertFalse(F(144, -89) < float('nan'))
     689  
     690      def testMixedLessEqual(self):
     691          self.assertTrue(0.5 <= F(1, 2))
     692          self.assertFalse(0.6 <= F(1, 2))
     693          self.assertTrue(F(1, 2) <= 0.5)
     694          self.assertFalse(F(1, 2) <= 0.4)
     695          self.assertTrue(2 <= F(4, 2))
     696          self.assertFalse(2 <= F(3, 2))
     697          self.assertTrue(F(4, 2) <= 2)
     698          self.assertFalse(F(5, 2) <= 2)
     699  
     700          self.assertFalse(float('inf') <= F(1, 2))
     701          self.assertTrue(float('-inf') <= F(0, 10))
     702          self.assertFalse(float('nan') <= F(-3, 7))
     703          self.assertTrue(F(1, 2) <= float('inf'))
     704          self.assertFalse(F(17, 12) <= float('-inf'))
     705          self.assertFalse(F(144, -89) <= float('nan'))
     706  
     707      def testBigFloatComparisons(self):
     708          # Because 10**23 can't be represented exactly as a float:
     709          self.assertFalse(F(10**23) == float(10**23))
     710          # The first test demonstrates why these are important.
     711          self.assertFalse(1e23 < float(F(math.trunc(1e23) + 1)))
     712          self.assertTrue(1e23 < F(math.trunc(1e23) + 1))
     713          self.assertFalse(1e23 <= F(math.trunc(1e23) - 1))
     714          self.assertTrue(1e23 > F(math.trunc(1e23) - 1))
     715          self.assertFalse(1e23 >= F(math.trunc(1e23) + 1))
     716  
     717      def testBigComplexComparisons(self):
     718          self.assertFalse(F(10**23) == complex(10**23))
     719          self.assertRaises(TypeError, operator.gt, F(10**23), complex(10**23))
     720          self.assertRaises(TypeError, operator.le, F(10**23), complex(10**23))
     721  
     722          x = F(3, 8)
     723          z = complex(0.375, 0.0)
     724          w = complex(0.375, 0.2)
     725          self.assertTrue(x == z)
     726          self.assertFalse(x != z)
     727          self.assertFalse(x == w)
     728          self.assertTrue(x != w)
     729          for op in operator.lt, operator.le, operator.gt, operator.ge:
     730              self.assertRaises(TypeError, op, x, z)
     731              self.assertRaises(TypeError, op, z, x)
     732              self.assertRaises(TypeError, op, x, w)
     733              self.assertRaises(TypeError, op, w, x)
     734  
     735      def testMixedEqual(self):
     736          self.assertTrue(0.5 == F(1, 2))
     737          self.assertFalse(0.6 == F(1, 2))
     738          self.assertTrue(F(1, 2) == 0.5)
     739          self.assertFalse(F(1, 2) == 0.4)
     740          self.assertTrue(2 == F(4, 2))
     741          self.assertFalse(2 == F(3, 2))
     742          self.assertTrue(F(4, 2) == 2)
     743          self.assertFalse(F(5, 2) == 2)
     744          self.assertFalse(F(5, 2) == float('nan'))
     745          self.assertFalse(float('nan') == F(3, 7))
     746          self.assertFalse(F(5, 2) == float('inf'))
     747          self.assertFalse(float('-inf') == F(2, 5))
     748  
     749      def testStringification(self):
     750          self.assertEqual("Fraction(7, 3)", repr(F(7, 3)))
     751          self.assertEqual("Fraction(6283185307, 2000000000)",
     752                           repr(F('3.1415926535')))
     753          self.assertEqual("Fraction(-1, 100000000000000000000)",
     754                           repr(F(1, -10**20)))
     755          self.assertEqual("7/3", str(F(7, 3)))
     756          self.assertEqual("7", str(F(7, 1)))
     757  
     758      def testHash(self):
     759          hmod = sys.hash_info.modulus
     760          hinf = sys.hash_info.inf
     761          self.assertEqual(hash(2.5), hash(F(5, 2)))
     762          self.assertEqual(hash(10**50), hash(F(10**50)))
     763          self.assertNotEqual(hash(float(10**23)), hash(F(10**23)))
     764          self.assertEqual(hinf, hash(F(1, hmod)))
     765          # Check that __hash__ produces the same value as hash(), for
     766          # consistency with int and Decimal.  (See issue #10356.)
     767          self.assertEqual(hash(F(-1)), F(-1).__hash__())
     768  
     769      def testApproximatePi(self):
     770          # Algorithm borrowed from
     771          # http://docs.python.org/lib/decimal-recipes.html
     772          three = F(3)
     773          lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
     774          while abs(s - lasts) > F(1, 10**9):
     775              lasts = s
     776              n, na = n+na, na+8
     777              d, da = d+da, da+32
     778              t = (t * n) / d
     779              s += t
     780          self.assertAlmostEqual(math.pi, s)
     781  
     782      def testApproximateCos1(self):
     783          # Algorithm borrowed from
     784          # http://docs.python.org/lib/decimal-recipes.html
     785          x = F(1)
     786          i, lasts, s, fact, num, sign = 0, 0, F(1), 1, 1, 1
     787          while abs(s - lasts) > F(1, 10**9):
     788              lasts = s
     789              i += 2
     790              fact *= i * (i-1)
     791              num *= x * x
     792              sign *= -1
     793              s += num / fact * sign
     794          self.assertAlmostEqual(math.cos(1), s)
     795  
     796      def test_copy_deepcopy_pickle(self):
     797          r = F(13, 7)
     798          dr = DummyFraction(13, 7)
     799          for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
     800              self.assertEqual(r, loads(dumps(r, proto)))
     801          self.assertEqual(id(r), id(copy(r)))
     802          self.assertEqual(id(r), id(deepcopy(r)))
     803          self.assertNotEqual(id(dr), id(copy(dr)))
     804          self.assertNotEqual(id(dr), id(deepcopy(dr)))
     805          self.assertTypedEquals(dr, copy(dr))
     806          self.assertTypedEquals(dr, deepcopy(dr))
     807  
     808      def test_slots(self):
     809          # Issue 4998
     810          r = F(13, 7)
     811          self.assertRaises(AttributeError, setattr, r, 'a', 10)
     812  
     813      def test_int_subclass(self):
     814          class ESC[4;38;5;81mmyint(ESC[4;38;5;149mint):
     815              def __mul__(self, other):
     816                  return type(self)(int(self) * int(other))
     817              def __floordiv__(self, other):
     818                  return type(self)(int(self) // int(other))
     819              def __mod__(self, other):
     820                  x = type(self)(int(self) % int(other))
     821                  return x
     822              @property
     823              def numerator(self):
     824                  return type(self)(int(self))
     825              @property
     826              def denominator(self):
     827                  return type(self)(1)
     828  
     829          f = fractions.Fraction(myint(1 * 3), myint(2 * 3))
     830          self.assertEqual(f.numerator, 1)
     831          self.assertEqual(f.denominator, 2)
     832          self.assertEqual(type(f.numerator), myint)
     833          self.assertEqual(type(f.denominator), myint)
     834  
     835  
     836  if __name__ == '__main__':
     837      unittest.main()