python (3.12.0)

(root)/
lib/
python3.12/
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("3 / 2")))
     166          self.assertEqual((3, 2), _components(F(" \n  +3/2")))
     167          self.assertEqual((-3, 2), _components(F("-3/2  ")))
     168          self.assertEqual((13, 2), _components(F("    013/02 \n  ")))
     169          self.assertEqual((16, 5), _components(F(" 3.2 ")))
     170          self.assertEqual((-16, 5), _components(F(" -3.2 ")))
     171          self.assertEqual((-3, 1), _components(F(" -3. ")))
     172          self.assertEqual((3, 5), _components(F(" .6 ")))
     173          self.assertEqual((1, 3125), _components(F("32.e-5")))
     174          self.assertEqual((1000000, 1), _components(F("1E+06")))
     175          self.assertEqual((-12300, 1), _components(F("-1.23e4")))
     176          self.assertEqual((0, 1), _components(F(" .0e+0\t")))
     177          self.assertEqual((0, 1), _components(F("-0.000e0")))
     178          self.assertEqual((123, 1), _components(F("1_2_3")))
     179          self.assertEqual((41, 107), _components(F("1_2_3/3_2_1")))
     180          self.assertEqual((6283, 2000), _components(F("3.14_15")))
     181          self.assertEqual((6283, 2*10**13), _components(F("3.14_15e-1_0")))
     182          self.assertEqual((101, 100), _components(F("1.01")))
     183          self.assertEqual((101, 100), _components(F("1.0_1")))
     184  
     185          self.assertRaisesMessage(
     186              ZeroDivisionError, "Fraction(3, 0)",
     187              F, "3/0")
     188          self.assertRaisesMessage(
     189              ValueError, "Invalid literal for Fraction: '3/'",
     190              F, "3/")
     191          self.assertRaisesMessage(
     192              ValueError, "Invalid literal for Fraction: '/2'",
     193              F, "/2")
     194          self.assertRaisesMessage(
     195              # Denominators don't need a sign.
     196              ValueError, "Invalid literal for Fraction: '3/+2'",
     197              F, "3/+2")
     198          self.assertRaisesMessage(
     199              # Imitate float's parsing.
     200              ValueError, "Invalid literal for Fraction: '+ 3/2'",
     201              F, "+ 3/2")
     202          self.assertRaisesMessage(
     203              # Avoid treating '.' as a regex special character.
     204              ValueError, "Invalid literal for Fraction: '3a2'",
     205              F, "3a2")
     206          self.assertRaisesMessage(
     207              # Don't accept combinations of decimals and rationals.
     208              ValueError, "Invalid literal for Fraction: '3/7.2'",
     209              F, "3/7.2")
     210          self.assertRaisesMessage(
     211              # Don't accept combinations of decimals and rationals.
     212              ValueError, "Invalid literal for Fraction: '3.2/7'",
     213              F, "3.2/7")
     214          self.assertRaisesMessage(
     215              # Allow 3. and .3, but not .
     216              ValueError, "Invalid literal for Fraction: '.'",
     217              F, ".")
     218          self.assertRaisesMessage(
     219              ValueError, "Invalid literal for Fraction: '_'",
     220              F, "_")
     221          self.assertRaisesMessage(
     222              ValueError, "Invalid literal for Fraction: '_1'",
     223              F, "_1")
     224          self.assertRaisesMessage(
     225              ValueError, "Invalid literal for Fraction: '1__2'",
     226              F, "1__2")
     227          self.assertRaisesMessage(
     228              ValueError, "Invalid literal for Fraction: '/_'",
     229              F, "/_")
     230          self.assertRaisesMessage(
     231              ValueError, "Invalid literal for Fraction: '1_/'",
     232              F, "1_/")
     233          self.assertRaisesMessage(
     234              ValueError, "Invalid literal for Fraction: '_1/'",
     235              F, "_1/")
     236          self.assertRaisesMessage(
     237              ValueError, "Invalid literal for Fraction: '1__2/'",
     238              F, "1__2/")
     239          self.assertRaisesMessage(
     240              ValueError, "Invalid literal for Fraction: '1/_'",
     241              F, "1/_")
     242          self.assertRaisesMessage(
     243              ValueError, "Invalid literal for Fraction: '1/_1'",
     244              F, "1/_1")
     245          self.assertRaisesMessage(
     246              ValueError, "Invalid literal for Fraction: '1/1__2'",
     247              F, "1/1__2")
     248          self.assertRaisesMessage(
     249              ValueError, "Invalid literal for Fraction: '1._111'",
     250              F, "1._111")
     251          self.assertRaisesMessage(
     252              ValueError, "Invalid literal for Fraction: '1.1__1'",
     253              F, "1.1__1")
     254          self.assertRaisesMessage(
     255              ValueError, "Invalid literal for Fraction: '1.1e+_1'",
     256              F, "1.1e+_1")
     257          self.assertRaisesMessage(
     258              ValueError, "Invalid literal for Fraction: '1.1e+1__1'",
     259              F, "1.1e+1__1")
     260          # Test catastrophic backtracking.
     261          val = "9"*50 + "_"
     262          self.assertRaisesMessage(
     263              ValueError, "Invalid literal for Fraction: '" + val + "'",
     264              F, val)
     265          self.assertRaisesMessage(
     266              ValueError, "Invalid literal for Fraction: '1/" + val + "'",
     267              F, "1/" + val)
     268          self.assertRaisesMessage(
     269              ValueError, "Invalid literal for Fraction: '1." + val + "'",
     270              F, "1." + val)
     271          self.assertRaisesMessage(
     272              ValueError, "Invalid literal for Fraction: '1.1+e" + val + "'",
     273              F, "1.1+e" + val)
     274  
     275      def testImmutable(self):
     276          r = F(7, 3)
     277          r.__init__(2, 15)
     278          self.assertEqual((7, 3), _components(r))
     279  
     280          self.assertRaises(AttributeError, setattr, r, 'numerator', 12)
     281          self.assertRaises(AttributeError, setattr, r, 'denominator', 6)
     282          self.assertEqual((7, 3), _components(r))
     283  
     284          # But if you _really_ need to:
     285          r._numerator = 4
     286          r._denominator = 2
     287          self.assertEqual((4, 2), _components(r))
     288          # Which breaks some important operations:
     289          self.assertNotEqual(F(4, 2), r)
     290  
     291      def testFromFloat(self):
     292          self.assertRaises(TypeError, F.from_float, 3+4j)
     293          self.assertEqual((10, 1), _components(F.from_float(10)))
     294          bigint = 1234567890123456789
     295          self.assertEqual((bigint, 1), _components(F.from_float(bigint)))
     296          self.assertEqual((0, 1), _components(F.from_float(-0.0)))
     297          self.assertEqual((10, 1), _components(F.from_float(10.0)))
     298          self.assertEqual((-5, 2), _components(F.from_float(-2.5)))
     299          self.assertEqual((99999999999999991611392, 1),
     300                           _components(F.from_float(1e23)))
     301          self.assertEqual(float(10**23), float(F.from_float(1e23)))
     302          self.assertEqual((3602879701896397, 1125899906842624),
     303                           _components(F.from_float(3.2)))
     304          self.assertEqual(3.2, float(F.from_float(3.2)))
     305  
     306          inf = 1e1000
     307          nan = inf - inf
     308          # bug 16469: error types should be consistent with float -> int
     309          self.assertRaisesMessage(
     310              OverflowError, "cannot convert Infinity to integer ratio",
     311              F.from_float, inf)
     312          self.assertRaisesMessage(
     313              OverflowError, "cannot convert Infinity to integer ratio",
     314              F.from_float, -inf)
     315          self.assertRaisesMessage(
     316              ValueError, "cannot convert NaN to integer ratio",
     317              F.from_float, nan)
     318  
     319      def testFromDecimal(self):
     320          self.assertRaises(TypeError, F.from_decimal, 3+4j)
     321          self.assertEqual(F(10, 1), F.from_decimal(10))
     322          self.assertEqual(F(0), F.from_decimal(Decimal("-0")))
     323          self.assertEqual(F(5, 10), F.from_decimal(Decimal("0.5")))
     324          self.assertEqual(F(5, 1000), F.from_decimal(Decimal("5e-3")))
     325          self.assertEqual(F(5000), F.from_decimal(Decimal("5e3")))
     326          self.assertEqual(1 - F(1, 10**30),
     327                           F.from_decimal(Decimal("0." + "9" * 30)))
     328  
     329          # bug 16469: error types should be consistent with decimal -> int
     330          self.assertRaisesMessage(
     331              OverflowError, "cannot convert Infinity to integer ratio",
     332              F.from_decimal, Decimal("inf"))
     333          self.assertRaisesMessage(
     334              OverflowError, "cannot convert Infinity to integer ratio",
     335              F.from_decimal, Decimal("-inf"))
     336          self.assertRaisesMessage(
     337              ValueError, "cannot convert NaN to integer ratio",
     338              F.from_decimal, Decimal("nan"))
     339          self.assertRaisesMessage(
     340              ValueError, "cannot convert NaN to integer ratio",
     341              F.from_decimal, Decimal("snan"))
     342  
     343      def test_is_integer(self):
     344          self.assertTrue(F(1, 1).is_integer())
     345          self.assertTrue(F(-1, 1).is_integer())
     346          self.assertTrue(F(1, -1).is_integer())
     347          self.assertTrue(F(2, 2).is_integer())
     348          self.assertTrue(F(-2, 2).is_integer())
     349          self.assertTrue(F(2, -2).is_integer())
     350  
     351          self.assertFalse(F(1, 2).is_integer())
     352          self.assertFalse(F(-1, 2).is_integer())
     353          self.assertFalse(F(1, -2).is_integer())
     354          self.assertFalse(F(-1, -2).is_integer())
     355  
     356      def test_as_integer_ratio(self):
     357          self.assertEqual(F(4, 6).as_integer_ratio(), (2, 3))
     358          self.assertEqual(F(-4, 6).as_integer_ratio(), (-2, 3))
     359          self.assertEqual(F(4, -6).as_integer_ratio(), (-2, 3))
     360          self.assertEqual(F(0, 6).as_integer_ratio(), (0, 1))
     361  
     362      def testLimitDenominator(self):
     363          rpi = F('3.1415926535897932')
     364          self.assertEqual(rpi.limit_denominator(10000), F(355, 113))
     365          self.assertEqual(-rpi.limit_denominator(10000), F(-355, 113))
     366          self.assertEqual(rpi.limit_denominator(113), F(355, 113))
     367          self.assertEqual(rpi.limit_denominator(112), F(333, 106))
     368          self.assertEqual(F(201, 200).limit_denominator(100), F(1))
     369          self.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
     370          self.assertEqual(F(0).limit_denominator(10000), F(0))
     371          for i in (0, -1):
     372              self.assertRaisesMessage(
     373                  ValueError, "max_denominator should be at least 1",
     374                  F(1).limit_denominator, i)
     375  
     376      def testConversions(self):
     377          self.assertTypedEquals(-1, math.trunc(F(-11, 10)))
     378          self.assertTypedEquals(1, math.trunc(F(11, 10)))
     379          self.assertTypedEquals(-2, math.floor(F(-11, 10)))
     380          self.assertTypedEquals(-1, math.ceil(F(-11, 10)))
     381          self.assertTypedEquals(-1, math.ceil(F(-10, 10)))
     382          self.assertTypedEquals(-1, int(F(-11, 10)))
     383          self.assertTypedEquals(0, round(F(-1, 10)))
     384          self.assertTypedEquals(0, round(F(-5, 10)))
     385          self.assertTypedEquals(-2, round(F(-15, 10)))
     386          self.assertTypedEquals(-1, round(F(-7, 10)))
     387  
     388          self.assertEqual(False, bool(F(0, 1)))
     389          self.assertEqual(True, bool(F(3, 2)))
     390          self.assertTypedEquals(0.1, float(F(1, 10)))
     391  
     392          # Check that __float__ isn't implemented by converting the
     393          # numerator and denominator to float before dividing.
     394          self.assertRaises(OverflowError, float, int('2'*400+'7'))
     395          self.assertAlmostEqual(2.0/3,
     396                                 float(F(int('2'*400+'7'), int('3'*400+'1'))))
     397  
     398          self.assertTypedEquals(0.1+0j, complex(F(1,10)))
     399  
     400      def testSupportsInt(self):
     401          # See bpo-44547.
     402          f = F(3, 2)
     403          self.assertIsInstance(f, typing.SupportsInt)
     404          self.assertEqual(int(f), 1)
     405          self.assertEqual(type(int(f)), int)
     406  
     407      def testIntGuaranteesIntReturn(self):
     408          # Check that int(some_fraction) gives a result of exact type `int`
     409          # even if the fraction is using some other Integral type for its
     410          # numerator and denominator.
     411  
     412          class ESC[4;38;5;81mCustomInt(ESC[4;38;5;149mint):
     413              """
     414              Subclass of int with just enough machinery to convince the Fraction
     415              constructor to produce something with CustomInt numerator and
     416              denominator.
     417              """
     418  
     419              @property
     420              def numerator(self):
     421                  return self
     422  
     423              @property
     424              def denominator(self):
     425                  return CustomInt(1)
     426  
     427              def __mul__(self, other):
     428                  return CustomInt(int(self) * int(other))
     429  
     430              def __floordiv__(self, other):
     431                  return CustomInt(int(self) // int(other))
     432  
     433          f = F(CustomInt(13), CustomInt(5))
     434  
     435          self.assertIsInstance(f.numerator, CustomInt)
     436          self.assertIsInstance(f.denominator, CustomInt)
     437          self.assertIsInstance(f, typing.SupportsInt)
     438          self.assertEqual(int(f), 2)
     439          self.assertEqual(type(int(f)), int)
     440  
     441      def testBoolGuarateesBoolReturn(self):
     442          # Ensure that __bool__ is used on numerator which guarantees a bool
     443          # return.  See also bpo-39274.
     444          @functools.total_ordering
     445          class ESC[4;38;5;81mCustomValue:
     446              denominator = 1
     447  
     448              def __init__(self, value):
     449                  self.value = value
     450  
     451              def __bool__(self):
     452                  return bool(self.value)
     453  
     454              @property
     455              def numerator(self):
     456                  # required to preserve `self` during instantiation
     457                  return self
     458  
     459              def __eq__(self, other):
     460                  raise AssertionError("Avoid comparisons in Fraction.__bool__")
     461  
     462              __lt__ = __eq__
     463  
     464          # We did not implement all abstract methods, so register:
     465          numbers.Rational.register(CustomValue)
     466  
     467          numerator = CustomValue(1)
     468          r = F(numerator)
     469          # ensure the numerator was not lost during instantiation:
     470          self.assertIs(r.numerator, numerator)
     471          self.assertIs(bool(r), True)
     472  
     473          numerator = CustomValue(0)
     474          r = F(numerator)
     475          self.assertIs(bool(r), False)
     476  
     477      def testRound(self):
     478          self.assertTypedEquals(F(-200), round(F(-150), -2))
     479          self.assertTypedEquals(F(-200), round(F(-250), -2))
     480          self.assertTypedEquals(F(30), round(F(26), -1))
     481          self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1))
     482          self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1))
     483  
     484      def testArithmetic(self):
     485          self.assertEqual(F(1, 2), F(1, 10) + F(2, 5))
     486          self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5))
     487          self.assertEqual(F(1, 25), F(1, 10) * F(2, 5))
     488          self.assertEqual(F(5, 6), F(2, 3) * F(5, 4))
     489          self.assertEqual(F(1, 4), F(1, 10) / F(2, 5))
     490          self.assertEqual(F(-15, 8), F(3, 4) / F(-2, 5))
     491          self.assertRaises(ZeroDivisionError, operator.truediv, F(1), F(0))
     492          self.assertTypedEquals(2, F(9, 10) // F(2, 5))
     493          self.assertTypedEquals(10**23, F(10**23, 1) // F(1))
     494          self.assertEqual(F(5, 6), F(7, 3) % F(3, 2))
     495          self.assertEqual(F(2, 3), F(-7, 3) % F(3, 2))
     496          self.assertEqual((F(1), F(5, 6)), divmod(F(7, 3), F(3, 2)))
     497          self.assertEqual((F(-2), F(2, 3)), divmod(F(-7, 3), F(3, 2)))
     498          self.assertEqual(F(8, 27), F(2, 3) ** F(3))
     499          self.assertEqual(F(27, 8), F(2, 3) ** F(-3))
     500          self.assertTypedEquals(2.0, F(4) ** F(1, 2))
     501          self.assertEqual(F(1, 1), +F(1, 1))
     502          z = pow(F(-1), F(1, 2))
     503          self.assertAlmostEqual(z.real, 0)
     504          self.assertEqual(z.imag, 1)
     505          # Regression test for #27539.
     506          p = F(-1, 2) ** 0
     507          self.assertEqual(p, F(1, 1))
     508          self.assertEqual(p.numerator, 1)
     509          self.assertEqual(p.denominator, 1)
     510          p = F(-1, 2) ** -1
     511          self.assertEqual(p, F(-2, 1))
     512          self.assertEqual(p.numerator, -2)
     513          self.assertEqual(p.denominator, 1)
     514          p = F(-1, 2) ** -2
     515          self.assertEqual(p, F(4, 1))
     516          self.assertEqual(p.numerator, 4)
     517          self.assertEqual(p.denominator, 1)
     518  
     519      def testLargeArithmetic(self):
     520          self.assertTypedEquals(
     521              F(10101010100808080808080808101010101010000000000000000,
     522                1010101010101010101010101011111111101010101010101010101010101),
     523              F(10**35+1, 10**27+1) % F(10**27+1, 10**35-1)
     524          )
     525          self.assertTypedEquals(
     526              F(7, 1901475900342344102245054808064),
     527              F(-2**100, 3) % F(5, 2**100)
     528          )
     529          self.assertTypedTupleEquals(
     530              (9999999999999999,
     531               F(10101010100808080808080808101010101010000000000000000,
     532                 1010101010101010101010101011111111101010101010101010101010101)),
     533              divmod(F(10**35+1, 10**27+1), F(10**27+1, 10**35-1))
     534          )
     535          self.assertTypedEquals(
     536              -2 ** 200 // 15,
     537              F(-2**100, 3) // F(5, 2**100)
     538          )
     539          self.assertTypedEquals(
     540              1,
     541              F(5, 2**100) // F(3, 2**100)
     542          )
     543          self.assertTypedEquals(
     544              (1, F(2, 2**100)),
     545              divmod(F(5, 2**100), F(3, 2**100))
     546          )
     547          self.assertTypedTupleEquals(
     548              (-2 ** 200 // 15,
     549               F(7, 1901475900342344102245054808064)),
     550              divmod(F(-2**100, 3), F(5, 2**100))
     551          )
     552  
     553      def testMixedArithmetic(self):
     554          self.assertTypedEquals(F(11, 10), F(1, 10) + 1)
     555          self.assertTypedEquals(1.1, F(1, 10) + 1.0)
     556          self.assertTypedEquals(1.1 + 0j, F(1, 10) + (1.0 + 0j))
     557          self.assertTypedEquals(F(11, 10), 1 + F(1, 10))
     558          self.assertTypedEquals(1.1, 1.0 + F(1, 10))
     559          self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + F(1, 10))
     560  
     561          self.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
     562          self.assertTypedEquals(-0.9, F(1, 10) - 1.0)
     563          self.assertTypedEquals(-0.9 + 0j, F(1, 10) - (1.0 + 0j))
     564          self.assertTypedEquals(F(9, 10), 1 - F(1, 10))
     565          self.assertTypedEquals(0.9, 1.0 - F(1, 10))
     566          self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - F(1, 10))
     567  
     568          self.assertTypedEquals(F(1, 10), F(1, 10) * 1)
     569          self.assertTypedEquals(0.1, F(1, 10) * 1.0)
     570          self.assertTypedEquals(0.1 + 0j, F(1, 10) * (1.0 + 0j))
     571          self.assertTypedEquals(F(1, 10), 1 * F(1, 10))
     572          self.assertTypedEquals(0.1, 1.0 * F(1, 10))
     573          self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * F(1, 10))
     574  
     575          self.assertTypedEquals(F(1, 10), F(1, 10) / 1)
     576          self.assertTypedEquals(0.1, F(1, 10) / 1.0)
     577          self.assertTypedEquals(0.1 + 0j, F(1, 10) / (1.0 + 0j))
     578          self.assertTypedEquals(F(10, 1), 1 / F(1, 10))
     579          self.assertTypedEquals(10.0, 1.0 / F(1, 10))
     580          self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))
     581  
     582          self.assertTypedEquals(0, F(1, 10) // 1)
     583          self.assertTypedEquals(0.0, F(1, 10) // 1.0)
     584          self.assertTypedEquals(10, 1 // F(1, 10))
     585          self.assertTypedEquals(10**23, 10**22 // F(1, 10))
     586          self.assertTypedEquals(1.0 // 0.1, 1.0 // F(1, 10))
     587  
     588          self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
     589          self.assertTypedEquals(0.1, F(1, 10) % 1.0)
     590          self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
     591          self.assertTypedEquals(1.0 % 0.1, 1.0 % F(1, 10))
     592          self.assertTypedEquals(0.1, F(1, 10) % float('inf'))
     593          self.assertTypedEquals(float('-inf'), F(1, 10) % float('-inf'))
     594          self.assertTypedEquals(float('inf'), F(-1, 10) % float('inf'))
     595          self.assertTypedEquals(-0.1, F(-1, 10) % float('-inf'))
     596  
     597          self.assertTypedTupleEquals((0, F(1, 10)), divmod(F(1, 10), 1))
     598          self.assertTypedTupleEquals(divmod(0.1, 1.0), divmod(F(1, 10), 1.0))
     599          self.assertTypedTupleEquals((10, F(0)), divmod(1, F(1, 10)))
     600          self.assertTypedTupleEquals(divmod(1.0, 0.1), divmod(1.0, F(1, 10)))
     601          self.assertTypedTupleEquals(divmod(0.1, float('inf')), divmod(F(1, 10), float('inf')))
     602          self.assertTypedTupleEquals(divmod(0.1, float('-inf')), divmod(F(1, 10), float('-inf')))
     603          self.assertTypedTupleEquals(divmod(-0.1, float('inf')), divmod(F(-1, 10), float('inf')))
     604          self.assertTypedTupleEquals(divmod(-0.1, float('-inf')), divmod(F(-1, 10), float('-inf')))
     605  
     606          # ** has more interesting conversion rules.
     607          self.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
     608          self.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
     609          self.assertTypedEquals(0.1, F(1, 10) ** 1.0)
     610          self.assertTypedEquals(0.1 + 0j, F(1, 10) ** (1.0 + 0j))
     611          self.assertTypedEquals(4 , 2 ** F(2, 1))
     612          z = pow(-1, F(1, 2))
     613          self.assertAlmostEqual(0, z.real)
     614          self.assertEqual(1, z.imag)
     615          self.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
     616          self.assertTypedEquals(2.0 , 4 ** F(1, 2))
     617          self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
     618          self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
     619          self.assertRaises(ZeroDivisionError, operator.pow,
     620                            F(0, 1), -2)
     621  
     622      def testMixingWithDecimal(self):
     623          # Decimal refuses mixed arithmetic (but not mixed comparisons)
     624          self.assertRaises(TypeError, operator.add,
     625                            F(3,11), Decimal('3.1415926'))
     626          self.assertRaises(TypeError, operator.add,
     627                            Decimal('3.1415926'), F(3,11))
     628  
     629      def testComparisons(self):
     630          self.assertTrue(F(1, 2) < F(2, 3))
     631          self.assertFalse(F(1, 2) < F(1, 2))
     632          self.assertTrue(F(1, 2) <= F(2, 3))
     633          self.assertTrue(F(1, 2) <= F(1, 2))
     634          self.assertFalse(F(2, 3) <= F(1, 2))
     635          self.assertTrue(F(1, 2) == F(1, 2))
     636          self.assertFalse(F(1, 2) == F(1, 3))
     637          self.assertFalse(F(1, 2) != F(1, 2))
     638          self.assertTrue(F(1, 2) != F(1, 3))
     639  
     640      def testComparisonsDummyRational(self):
     641          self.assertTrue(F(1, 2) == DummyRational(1, 2))
     642          self.assertTrue(DummyRational(1, 2) == F(1, 2))
     643          self.assertFalse(F(1, 2) == DummyRational(3, 4))
     644          self.assertFalse(DummyRational(3, 4) == F(1, 2))
     645  
     646          self.assertTrue(F(1, 2) < DummyRational(3, 4))
     647          self.assertFalse(F(1, 2) < DummyRational(1, 2))
     648          self.assertFalse(F(1, 2) < DummyRational(1, 7))
     649          self.assertFalse(F(1, 2) > DummyRational(3, 4))
     650          self.assertFalse(F(1, 2) > DummyRational(1, 2))
     651          self.assertTrue(F(1, 2) > DummyRational(1, 7))
     652          self.assertTrue(F(1, 2) <= DummyRational(3, 4))
     653          self.assertTrue(F(1, 2) <= DummyRational(1, 2))
     654          self.assertFalse(F(1, 2) <= DummyRational(1, 7))
     655          self.assertFalse(F(1, 2) >= DummyRational(3, 4))
     656          self.assertTrue(F(1, 2) >= DummyRational(1, 2))
     657          self.assertTrue(F(1, 2) >= DummyRational(1, 7))
     658  
     659          self.assertTrue(DummyRational(1, 2) < F(3, 4))
     660          self.assertFalse(DummyRational(1, 2) < F(1, 2))
     661          self.assertFalse(DummyRational(1, 2) < F(1, 7))
     662          self.assertFalse(DummyRational(1, 2) > F(3, 4))
     663          self.assertFalse(DummyRational(1, 2) > F(1, 2))
     664          self.assertTrue(DummyRational(1, 2) > F(1, 7))
     665          self.assertTrue(DummyRational(1, 2) <= F(3, 4))
     666          self.assertTrue(DummyRational(1, 2) <= F(1, 2))
     667          self.assertFalse(DummyRational(1, 2) <= F(1, 7))
     668          self.assertFalse(DummyRational(1, 2) >= F(3, 4))
     669          self.assertTrue(DummyRational(1, 2) >= F(1, 2))
     670          self.assertTrue(DummyRational(1, 2) >= F(1, 7))
     671  
     672      def testComparisonsDummyFloat(self):
     673          x = DummyFloat(1./3.)
     674          y = F(1, 3)
     675          self.assertTrue(x != y)
     676          self.assertTrue(x < y or x > y)
     677          self.assertFalse(x == y)
     678          self.assertFalse(x <= y and x >= y)
     679          self.assertTrue(y != x)
     680          self.assertTrue(y < x or y > x)
     681          self.assertFalse(y == x)
     682          self.assertFalse(y <= x and y >= x)
     683  
     684      def testMixedLess(self):
     685          self.assertTrue(2 < F(5, 2))
     686          self.assertFalse(2 < F(4, 2))
     687          self.assertTrue(F(5, 2) < 3)
     688          self.assertFalse(F(4, 2) < 2)
     689  
     690          self.assertTrue(F(1, 2) < 0.6)
     691          self.assertFalse(F(1, 2) < 0.4)
     692          self.assertTrue(0.4 < F(1, 2))
     693          self.assertFalse(0.5 < F(1, 2))
     694  
     695          self.assertFalse(float('inf') < F(1, 2))
     696          self.assertTrue(float('-inf') < F(0, 10))
     697          self.assertFalse(float('nan') < F(-3, 7))
     698          self.assertTrue(F(1, 2) < float('inf'))
     699          self.assertFalse(F(17, 12) < float('-inf'))
     700          self.assertFalse(F(144, -89) < float('nan'))
     701  
     702      def testMixedLessEqual(self):
     703          self.assertTrue(0.5 <= F(1, 2))
     704          self.assertFalse(0.6 <= F(1, 2))
     705          self.assertTrue(F(1, 2) <= 0.5)
     706          self.assertFalse(F(1, 2) <= 0.4)
     707          self.assertTrue(2 <= F(4, 2))
     708          self.assertFalse(2 <= F(3, 2))
     709          self.assertTrue(F(4, 2) <= 2)
     710          self.assertFalse(F(5, 2) <= 2)
     711  
     712          self.assertFalse(float('inf') <= F(1, 2))
     713          self.assertTrue(float('-inf') <= F(0, 10))
     714          self.assertFalse(float('nan') <= F(-3, 7))
     715          self.assertTrue(F(1, 2) <= float('inf'))
     716          self.assertFalse(F(17, 12) <= float('-inf'))
     717          self.assertFalse(F(144, -89) <= float('nan'))
     718  
     719      def testBigFloatComparisons(self):
     720          # Because 10**23 can't be represented exactly as a float:
     721          self.assertFalse(F(10**23) == float(10**23))
     722          # The first test demonstrates why these are important.
     723          self.assertFalse(1e23 < float(F(math.trunc(1e23) + 1)))
     724          self.assertTrue(1e23 < F(math.trunc(1e23) + 1))
     725          self.assertFalse(1e23 <= F(math.trunc(1e23) - 1))
     726          self.assertTrue(1e23 > F(math.trunc(1e23) - 1))
     727          self.assertFalse(1e23 >= F(math.trunc(1e23) + 1))
     728  
     729      def testBigComplexComparisons(self):
     730          self.assertFalse(F(10**23) == complex(10**23))
     731          self.assertRaises(TypeError, operator.gt, F(10**23), complex(10**23))
     732          self.assertRaises(TypeError, operator.le, F(10**23), complex(10**23))
     733  
     734          x = F(3, 8)
     735          z = complex(0.375, 0.0)
     736          w = complex(0.375, 0.2)
     737          self.assertTrue(x == z)
     738          self.assertFalse(x != z)
     739          self.assertFalse(x == w)
     740          self.assertTrue(x != w)
     741          for op in operator.lt, operator.le, operator.gt, operator.ge:
     742              self.assertRaises(TypeError, op, x, z)
     743              self.assertRaises(TypeError, op, z, x)
     744              self.assertRaises(TypeError, op, x, w)
     745              self.assertRaises(TypeError, op, w, x)
     746  
     747      def testMixedEqual(self):
     748          self.assertTrue(0.5 == F(1, 2))
     749          self.assertFalse(0.6 == F(1, 2))
     750          self.assertTrue(F(1, 2) == 0.5)
     751          self.assertFalse(F(1, 2) == 0.4)
     752          self.assertTrue(2 == F(4, 2))
     753          self.assertFalse(2 == F(3, 2))
     754          self.assertTrue(F(4, 2) == 2)
     755          self.assertFalse(F(5, 2) == 2)
     756          self.assertFalse(F(5, 2) == float('nan'))
     757          self.assertFalse(float('nan') == F(3, 7))
     758          self.assertFalse(F(5, 2) == float('inf'))
     759          self.assertFalse(float('-inf') == F(2, 5))
     760  
     761      def testStringification(self):
     762          self.assertEqual("Fraction(7, 3)", repr(F(7, 3)))
     763          self.assertEqual("Fraction(6283185307, 2000000000)",
     764                           repr(F('3.1415926535')))
     765          self.assertEqual("Fraction(-1, 100000000000000000000)",
     766                           repr(F(1, -10**20)))
     767          self.assertEqual("7/3", str(F(7, 3)))
     768          self.assertEqual("7", str(F(7, 1)))
     769  
     770      def testHash(self):
     771          hmod = sys.hash_info.modulus
     772          hinf = sys.hash_info.inf
     773          self.assertEqual(hash(2.5), hash(F(5, 2)))
     774          self.assertEqual(hash(10**50), hash(F(10**50)))
     775          self.assertNotEqual(hash(float(10**23)), hash(F(10**23)))
     776          self.assertEqual(hinf, hash(F(1, hmod)))
     777          # Check that __hash__ produces the same value as hash(), for
     778          # consistency with int and Decimal.  (See issue #10356.)
     779          self.assertEqual(hash(F(-1)), F(-1).__hash__())
     780  
     781      def testApproximatePi(self):
     782          # Algorithm borrowed from
     783          # http://docs.python.org/lib/decimal-recipes.html
     784          three = F(3)
     785          lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
     786          while abs(s - lasts) > F(1, 10**9):
     787              lasts = s
     788              n, na = n+na, na+8
     789              d, da = d+da, da+32
     790              t = (t * n) / d
     791              s += t
     792          self.assertAlmostEqual(math.pi, s)
     793  
     794      def testApproximateCos1(self):
     795          # Algorithm borrowed from
     796          # http://docs.python.org/lib/decimal-recipes.html
     797          x = F(1)
     798          i, lasts, s, fact, num, sign = 0, 0, F(1), 1, 1, 1
     799          while abs(s - lasts) > F(1, 10**9):
     800              lasts = s
     801              i += 2
     802              fact *= i * (i-1)
     803              num *= x * x
     804              sign *= -1
     805              s += num / fact * sign
     806          self.assertAlmostEqual(math.cos(1), s)
     807  
     808      def test_copy_deepcopy_pickle(self):
     809          r = F(13, 7)
     810          dr = DummyFraction(13, 7)
     811          for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
     812              self.assertEqual(r, loads(dumps(r, proto)))
     813          self.assertEqual(id(r), id(copy(r)))
     814          self.assertEqual(id(r), id(deepcopy(r)))
     815          self.assertNotEqual(id(dr), id(copy(dr)))
     816          self.assertNotEqual(id(dr), id(deepcopy(dr)))
     817          self.assertTypedEquals(dr, copy(dr))
     818          self.assertTypedEquals(dr, deepcopy(dr))
     819  
     820      def test_slots(self):
     821          # Issue 4998
     822          r = F(13, 7)
     823          self.assertRaises(AttributeError, setattr, r, 'a', 10)
     824  
     825      def test_int_subclass(self):
     826          class ESC[4;38;5;81mmyint(ESC[4;38;5;149mint):
     827              def __mul__(self, other):
     828                  return type(self)(int(self) * int(other))
     829              def __floordiv__(self, other):
     830                  return type(self)(int(self) // int(other))
     831              def __mod__(self, other):
     832                  x = type(self)(int(self) % int(other))
     833                  return x
     834              @property
     835              def numerator(self):
     836                  return type(self)(int(self))
     837              @property
     838              def denominator(self):
     839                  return type(self)(1)
     840  
     841          f = fractions.Fraction(myint(1 * 3), myint(2 * 3))
     842          self.assertEqual(f.numerator, 1)
     843          self.assertEqual(f.denominator, 2)
     844          self.assertEqual(type(f.numerator), myint)
     845          self.assertEqual(type(f.denominator), myint)
     846  
     847      def test_format_no_presentation_type(self):
     848          # Triples (fraction, specification, expected_result)
     849          testcases = [
     850              (F(1, 3), '', '1/3'),
     851              (F(-1, 3), '', '-1/3'),
     852              (F(3), '', '3'),
     853              (F(-3), '', '-3'),
     854          ]
     855          for fraction, spec, expected in testcases:
     856              with self.subTest(fraction=fraction, spec=spec):
     857                  self.assertEqual(format(fraction, spec), expected)
     858  
     859      def test_format_e_presentation_type(self):
     860          # Triples (fraction, specification, expected_result)
     861          testcases = [
     862              (F(2, 3), '.6e', '6.666667e-01'),
     863              (F(3, 2), '.6e', '1.500000e+00'),
     864              (F(2, 13), '.6e', '1.538462e-01'),
     865              (F(2, 23), '.6e', '8.695652e-02'),
     866              (F(2, 33), '.6e', '6.060606e-02'),
     867              (F(13, 2), '.6e', '6.500000e+00'),
     868              (F(20, 2), '.6e', '1.000000e+01'),
     869              (F(23, 2), '.6e', '1.150000e+01'),
     870              (F(33, 2), '.6e', '1.650000e+01'),
     871              (F(2, 3), '.6e', '6.666667e-01'),
     872              (F(3, 2), '.6e', '1.500000e+00'),
     873              # Zero
     874              (F(0), '.3e', '0.000e+00'),
     875              # Powers of 10, to exercise the log10 boundary logic
     876              (F(1, 1000), '.3e', '1.000e-03'),
     877              (F(1, 100), '.3e', '1.000e-02'),
     878              (F(1, 10), '.3e', '1.000e-01'),
     879              (F(1, 1), '.3e', '1.000e+00'),
     880              (F(10), '.3e', '1.000e+01'),
     881              (F(100), '.3e', '1.000e+02'),
     882              (F(1000), '.3e', '1.000e+03'),
     883              # Boundary where we round up to the next power of 10
     884              (F('99.999994999999'), '.6e', '9.999999e+01'),
     885              (F('99.999995'), '.6e', '1.000000e+02'),
     886              (F('99.999995000001'), '.6e', '1.000000e+02'),
     887              # Negatives
     888              (F(-2, 3), '.6e', '-6.666667e-01'),
     889              (F(-3, 2), '.6e', '-1.500000e+00'),
     890              (F(-100), '.6e', '-1.000000e+02'),
     891              # Large and small
     892              (F('1e1000'), '.3e', '1.000e+1000'),
     893              (F('1e-1000'), '.3e', '1.000e-1000'),
     894              # Using 'E' instead of 'e' should give us a capital 'E'
     895              (F(2, 3), '.6E', '6.666667E-01'),
     896              # Tiny precision
     897              (F(2, 3), '.1e', '6.7e-01'),
     898              (F('0.995'), '.0e', '1e+00'),
     899              # Default precision is 6
     900              (F(22, 7), 'e', '3.142857e+00'),
     901              # Alternate form forces a decimal point
     902              (F('0.995'), '#.0e', '1.e+00'),
     903              # Check that padding takes the exponent into account.
     904              (F(22, 7), '11.6e', '3.142857e+00'),
     905              (F(22, 7), '12.6e', '3.142857e+00'),
     906              (F(22, 7), '13.6e', ' 3.142857e+00'),
     907              # Thousands separators
     908              (F('1234567.123456'), ',.5e', '1.23457e+06'),
     909              (F('123.123456'), '012_.2e', '0_001.23e+02'),
     910              # z flag is legal, but never makes a difference to the output
     911              (F(-1, 7**100), 'z.6e', '-3.091690e-85'),
     912          ]
     913          for fraction, spec, expected in testcases:
     914              with self.subTest(fraction=fraction, spec=spec):
     915                  self.assertEqual(format(fraction, spec), expected)
     916  
     917      def test_format_f_presentation_type(self):
     918          # Triples (fraction, specification, expected_result)
     919          testcases = [
     920              # Simple .f formatting
     921              (F(0, 1), '.2f', '0.00'),
     922              (F(1, 3), '.2f', '0.33'),
     923              (F(2, 3), '.2f', '0.67'),
     924              (F(4, 3), '.2f', '1.33'),
     925              (F(1, 8), '.2f', '0.12'),
     926              (F(3, 8), '.2f', '0.38'),
     927              (F(1, 13), '.2f', '0.08'),
     928              (F(1, 199), '.2f', '0.01'),
     929              (F(1, 200), '.2f', '0.00'),
     930              (F(22, 7), '.5f', '3.14286'),
     931              (F('399024789'), '.2f', '399024789.00'),
     932              # Large precision (more than float can provide)
     933              (F(104348, 33215), '.50f',
     934               '3.14159265392142104470871594159265392142104470871594'),
     935              # Precision defaults to 6 if not given
     936              (F(22, 7), 'f', '3.142857'),
     937              (F(0), 'f', '0.000000'),
     938              (F(-22, 7), 'f', '-3.142857'),
     939              # Round-ties-to-even checks
     940              (F('1.225'), '.2f', '1.22'),
     941              (F('1.2250000001'), '.2f', '1.23'),
     942              (F('1.2349999999'), '.2f', '1.23'),
     943              (F('1.235'), '.2f', '1.24'),
     944              (F('1.245'), '.2f', '1.24'),
     945              (F('1.2450000001'), '.2f', '1.25'),
     946              (F('1.2549999999'), '.2f', '1.25'),
     947              (F('1.255'), '.2f', '1.26'),
     948              (F('-1.225'), '.2f', '-1.22'),
     949              (F('-1.2250000001'), '.2f', '-1.23'),
     950              (F('-1.2349999999'), '.2f', '-1.23'),
     951              (F('-1.235'), '.2f', '-1.24'),
     952              (F('-1.245'), '.2f', '-1.24'),
     953              (F('-1.2450000001'), '.2f', '-1.25'),
     954              (F('-1.2549999999'), '.2f', '-1.25'),
     955              (F('-1.255'), '.2f', '-1.26'),
     956              # Negatives and sign handling
     957              (F(2, 3), '.2f', '0.67'),
     958              (F(2, 3), '-.2f', '0.67'),
     959              (F(2, 3), '+.2f', '+0.67'),
     960              (F(2, 3), ' .2f', ' 0.67'),
     961              (F(-2, 3), '.2f', '-0.67'),
     962              (F(-2, 3), '-.2f', '-0.67'),
     963              (F(-2, 3), '+.2f', '-0.67'),
     964              (F(-2, 3), ' .2f', '-0.67'),
     965              # Formatting to zero places
     966              (F(1, 2), '.0f', '0'),
     967              (F(-1, 2), '.0f', '-0'),
     968              (F(22, 7), '.0f', '3'),
     969              (F(-22, 7), '.0f', '-3'),
     970              # Formatting to zero places, alternate form
     971              (F(1, 2), '#.0f', '0.'),
     972              (F(-1, 2), '#.0f', '-0.'),
     973              (F(22, 7), '#.0f', '3.'),
     974              (F(-22, 7), '#.0f', '-3.'),
     975              # z flag for suppressing negative zeros
     976              (F('-0.001'), 'z.2f', '0.00'),
     977              (F('-0.001'), '-z.2f', '0.00'),
     978              (F('-0.001'), '+z.2f', '+0.00'),
     979              (F('-0.001'), ' z.2f', ' 0.00'),
     980              (F('0.001'), 'z.2f', '0.00'),
     981              (F('0.001'), '-z.2f', '0.00'),
     982              (F('0.001'), '+z.2f', '+0.00'),
     983              (F('0.001'), ' z.2f', ' 0.00'),
     984              # Specifying a minimum width
     985              (F(2, 3), '6.2f', '  0.67'),
     986              (F(12345), '6.2f', '12345.00'),
     987              (F(12345), '12f', '12345.000000'),
     988              # Fill and alignment
     989              (F(2, 3), '>6.2f', '  0.67'),
     990              (F(2, 3), '<6.2f', '0.67  '),
     991              (F(2, 3), '^3.2f', '0.67'),
     992              (F(2, 3), '^4.2f', '0.67'),
     993              (F(2, 3), '^5.2f', '0.67 '),
     994              (F(2, 3), '^6.2f', ' 0.67 '),
     995              (F(2, 3), '^7.2f', ' 0.67  '),
     996              (F(2, 3), '^8.2f', '  0.67  '),
     997              # '=' alignment
     998              (F(-2, 3), '=+8.2f', '-   0.67'),
     999              (F(2, 3), '=+8.2f', '+   0.67'),
    1000              # Fill character
    1001              (F(-2, 3), 'X>3.2f', '-0.67'),
    1002              (F(-2, 3), 'X>7.2f', 'XX-0.67'),
    1003              (F(-2, 3), 'X<7.2f', '-0.67XX'),
    1004              (F(-2, 3), 'X^7.2f', 'X-0.67X'),
    1005              (F(-2, 3), 'X=7.2f', '-XX0.67'),
    1006              (F(-2, 3), ' >7.2f', '  -0.67'),
    1007              # Corner cases: weird fill characters
    1008              (F(-2, 3), '\x00>7.2f', '\x00\x00-0.67'),
    1009              (F(-2, 3), '\n>7.2f', '\n\n-0.67'),
    1010              (F(-2, 3), '\t>7.2f', '\t\t-0.67'),
    1011              (F(-2, 3), '>>7.2f', '>>-0.67'),
    1012              (F(-2, 3), '<>7.2f', '<<-0.67'),
    1013              (F(-2, 3), '→>7.2f', '→→-0.67'),
    1014              # Zero-padding
    1015              (F(-2, 3), '07.2f', '-000.67'),
    1016              (F(-2, 3), '-07.2f', '-000.67'),
    1017              (F(2, 3), '+07.2f', '+000.67'),
    1018              (F(2, 3), ' 07.2f', ' 000.67'),
    1019              # An isolated zero is a minimum width, not a zero-pad flag.
    1020              # So unlike zero-padding, it's legal in combination with alignment.
    1021              (F(2, 3), '0.2f', '0.67'),
    1022              (F(2, 3), '>0.2f', '0.67'),
    1023              (F(2, 3), '<0.2f', '0.67'),
    1024              (F(2, 3), '^0.2f', '0.67'),
    1025              (F(2, 3), '=0.2f', '0.67'),
    1026              # Corner case: zero-padding _and_ a zero minimum width.
    1027              (F(2, 3), '00.2f', '0.67'),
    1028              # Thousands separator (only affects portion before the point)
    1029              (F(2, 3), ',.2f', '0.67'),
    1030              (F(2, 3), ',.7f', '0.6666667'),
    1031              (F('123456.789'), ',.2f', '123,456.79'),
    1032              (F('1234567'), ',.2f', '1,234,567.00'),
    1033              (F('12345678'), ',.2f', '12,345,678.00'),
    1034              (F('12345678'), ',f', '12,345,678.000000'),
    1035              # Underscore as thousands separator
    1036              (F(2, 3), '_.2f', '0.67'),
    1037              (F(2, 3), '_.7f', '0.6666667'),
    1038              (F('123456.789'), '_.2f', '123_456.79'),
    1039              (F('1234567'), '_.2f', '1_234_567.00'),
    1040              (F('12345678'), '_.2f', '12_345_678.00'),
    1041              # Thousands and zero-padding
    1042              (F('1234.5678'), '07,.2f', '1,234.57'),
    1043              (F('1234.5678'), '08,.2f', '1,234.57'),
    1044              (F('1234.5678'), '09,.2f', '01,234.57'),
    1045              (F('1234.5678'), '010,.2f', '001,234.57'),
    1046              (F('1234.5678'), '011,.2f', '0,001,234.57'),
    1047              (F('1234.5678'), '012,.2f', '0,001,234.57'),
    1048              (F('1234.5678'), '013,.2f', '00,001,234.57'),
    1049              (F('1234.5678'), '014,.2f', '000,001,234.57'),
    1050              (F('1234.5678'), '015,.2f', '0,000,001,234.57'),
    1051              (F('1234.5678'), '016,.2f', '0,000,001,234.57'),
    1052              (F('-1234.5678'), '07,.2f', '-1,234.57'),
    1053              (F('-1234.5678'), '08,.2f', '-1,234.57'),
    1054              (F('-1234.5678'), '09,.2f', '-1,234.57'),
    1055              (F('-1234.5678'), '010,.2f', '-01,234.57'),
    1056              (F('-1234.5678'), '011,.2f', '-001,234.57'),
    1057              (F('-1234.5678'), '012,.2f', '-0,001,234.57'),
    1058              (F('-1234.5678'), '013,.2f', '-0,001,234.57'),
    1059              (F('-1234.5678'), '014,.2f', '-00,001,234.57'),
    1060              (F('-1234.5678'), '015,.2f', '-000,001,234.57'),
    1061              (F('-1234.5678'), '016,.2f', '-0,000,001,234.57'),
    1062              # Corner case: no decimal point
    1063              (F('-1234.5678'), '06,.0f', '-1,235'),
    1064              (F('-1234.5678'), '07,.0f', '-01,235'),
    1065              (F('-1234.5678'), '08,.0f', '-001,235'),
    1066              (F('-1234.5678'), '09,.0f', '-0,001,235'),
    1067              # Corner-case - zero-padding specified through fill and align
    1068              # instead of the zero-pad character - in this case, treat '0' as a
    1069              # regular fill character and don't attempt to insert commas into
    1070              # the filled portion. This differs from the int and float
    1071              # behaviour.
    1072              (F('1234.5678'), '0=12,.2f', '00001,234.57'),
    1073              # Corner case where it's not clear whether the '0' indicates zero
    1074              # padding or gives the minimum width, but there's still an obvious
    1075              # answer to give. We want this to work in case the minimum width
    1076              # is being inserted programmatically: spec = f'{width}.2f'.
    1077              (F('12.34'), '0.2f', '12.34'),
    1078              (F('12.34'), 'X>0.2f', '12.34'),
    1079              # 'F' should work identically to 'f'
    1080              (F(22, 7), '.5F', '3.14286'),
    1081              # %-specifier
    1082              (F(22, 7), '.2%', '314.29%'),
    1083              (F(1, 7), '.2%', '14.29%'),
    1084              (F(1, 70), '.2%', '1.43%'),
    1085              (F(1, 700), '.2%', '0.14%'),
    1086              (F(1, 7000), '.2%', '0.01%'),
    1087              (F(1, 70000), '.2%', '0.00%'),
    1088              (F(1, 7), '.0%', '14%'),
    1089              (F(1, 7), '#.0%', '14.%'),
    1090              (F(100, 7), ',.2%', '1,428.57%'),
    1091              (F(22, 7), '7.2%', '314.29%'),
    1092              (F(22, 7), '8.2%', ' 314.29%'),
    1093              (F(22, 7), '08.2%', '0314.29%'),
    1094              # Test cases from #67790 and discuss.python.org Ideas thread.
    1095              (F(1, 3), '.2f', '0.33'),
    1096              (F(1, 8), '.2f', '0.12'),
    1097              (F(3, 8), '.2f', '0.38'),
    1098              (F(2545, 1000), '.2f', '2.54'),
    1099              (F(2549, 1000), '.2f', '2.55'),
    1100              (F(2635, 1000), '.2f', '2.64'),
    1101              (F(1, 100), '.1f', '0.0'),
    1102              (F(49, 1000), '.1f', '0.0'),
    1103              (F(51, 1000), '.1f', '0.1'),
    1104              (F(149, 1000), '.1f', '0.1'),
    1105              (F(151, 1000), '.1f', '0.2'),
    1106          ]
    1107          for fraction, spec, expected in testcases:
    1108              with self.subTest(fraction=fraction, spec=spec):
    1109                  self.assertEqual(format(fraction, spec), expected)
    1110  
    1111      def test_format_g_presentation_type(self):
    1112          # Triples (fraction, specification, expected_result)
    1113          testcases = [
    1114              (F('0.000012345678'), '.6g', '1.23457e-05'),
    1115              (F('0.00012345678'), '.6g', '0.000123457'),
    1116              (F('0.0012345678'), '.6g', '0.00123457'),
    1117              (F('0.012345678'), '.6g', '0.0123457'),
    1118              (F('0.12345678'), '.6g', '0.123457'),
    1119              (F('1.2345678'), '.6g', '1.23457'),
    1120              (F('12.345678'), '.6g', '12.3457'),
    1121              (F('123.45678'), '.6g', '123.457'),
    1122              (F('1234.5678'), '.6g', '1234.57'),
    1123              (F('12345.678'), '.6g', '12345.7'),
    1124              (F('123456.78'), '.6g', '123457'),
    1125              (F('1234567.8'), '.6g', '1.23457e+06'),
    1126              # Rounding up cases
    1127              (F('9.99999e+2'), '.4g', '1000'),
    1128              (F('9.99999e-8'), '.4g', '1e-07'),
    1129              (F('9.99999e+8'), '.4g', '1e+09'),
    1130              # Check round-ties-to-even behaviour
    1131              (F('-0.115'), '.2g', '-0.12'),
    1132              (F('-0.125'), '.2g', '-0.12'),
    1133              (F('-0.135'), '.2g', '-0.14'),
    1134              (F('-0.145'), '.2g', '-0.14'),
    1135              (F('0.115'), '.2g', '0.12'),
    1136              (F('0.125'), '.2g', '0.12'),
    1137              (F('0.135'), '.2g', '0.14'),
    1138              (F('0.145'), '.2g', '0.14'),
    1139              # Trailing zeros and decimal point suppressed by default ...
    1140              (F(0), '.6g', '0'),
    1141              (F('123.400'), '.6g', '123.4'),
    1142              (F('123.000'), '.6g', '123'),
    1143              (F('120.000'), '.6g', '120'),
    1144              (F('12000000'), '.6g', '1.2e+07'),
    1145              # ... but not when alternate form is in effect
    1146              (F(0), '#.6g', '0.00000'),
    1147              (F('123.400'), '#.6g', '123.400'),
    1148              (F('123.000'), '#.6g', '123.000'),
    1149              (F('120.000'), '#.6g', '120.000'),
    1150              (F('12000000'), '#.6g', '1.20000e+07'),
    1151              # 'G' format (uses 'E' instead of 'e' for the exponent indicator)
    1152              (F('123.45678'), '.6G', '123.457'),
    1153              (F('1234567.8'), '.6G', '1.23457E+06'),
    1154              # Default precision is 6 significant figures
    1155              (F('3.1415926535'), 'g', '3.14159'),
    1156              # Precision 0 is treated the same as precision 1.
    1157              (F('0.000031415'), '.0g', '3e-05'),
    1158              (F('0.00031415'), '.0g', '0.0003'),
    1159              (F('0.31415'), '.0g', '0.3'),
    1160              (F('3.1415'), '.0g', '3'),
    1161              (F('3.1415'), '#.0g', '3.'),
    1162              (F('31.415'), '.0g', '3e+01'),
    1163              (F('31.415'), '#.0g', '3.e+01'),
    1164              (F('0.000031415'), '.1g', '3e-05'),
    1165              (F('0.00031415'), '.1g', '0.0003'),
    1166              (F('0.31415'), '.1g', '0.3'),
    1167              (F('3.1415'), '.1g', '3'),
    1168              (F('3.1415'), '#.1g', '3.'),
    1169              (F('31.415'), '.1g', '3e+01'),
    1170              # Thousands separator
    1171              (F(2**64), '_.25g', '18_446_744_073_709_551_616'),
    1172              # As with 'e' format, z flag is legal, but has no effect
    1173              (F(-1, 7**100), 'zg', '-3.09169e-85'),
    1174          ]
    1175          for fraction, spec, expected in testcases:
    1176              with self.subTest(fraction=fraction, spec=spec):
    1177                  self.assertEqual(format(fraction, spec), expected)
    1178  
    1179      def test_invalid_formats(self):
    1180          fraction = F(2, 3)
    1181          with self.assertRaises(TypeError):
    1182              format(fraction, None)
    1183  
    1184          invalid_specs = [
    1185              'Q6f',  # regression test
    1186              # illegal to use fill or alignment when zero padding
    1187              'X>010f',
    1188              'X<010f',
    1189              'X^010f',
    1190              'X=010f',
    1191              '0>010f',
    1192              '0<010f',
    1193              '0^010f',
    1194              '0=010f',
    1195              '>010f',
    1196              '<010f',
    1197              '^010f',
    1198              '=010e',
    1199              '=010f',
    1200              '=010g',
    1201              '=010%',
    1202              '>00.2f',
    1203              '>00f',
    1204              # Too many zeros - minimum width should not have leading zeros
    1205              '006f',
    1206              # Leading zeros in precision
    1207              '.010f',
    1208              '.02f',
    1209              '.000f',
    1210              # Missing precision
    1211              '.e',
    1212              '.f',
    1213              '.g',
    1214              '.%',
    1215              # Z instead of z for negative zero suppression
    1216              'Z.2f'
    1217          ]
    1218          for spec in invalid_specs:
    1219              with self.subTest(spec=spec):
    1220                  with self.assertRaises(ValueError):
    1221                      format(fraction, spec)
    1222  
    1223  
    1224  if __name__ == '__main__':
    1225      unittest.main()