[Python-checkins] [3.11] gh-68163: Correct conversion of Rational instances to float (GH-25619) (#96556)

pablogsal webhook-mailer at python.org
Thu Sep 8 07:04:11 EDT 2022


https://github.com/python/cpython/commit/ae819ca6fd09e14a58842fc1e889f6737e53af0d
commit: ae819ca6fd09e14a58842fc1e889f6737e53af0d
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: pablogsal <Pablogsal at gmail.com>
date: 2022年09月08日T12:03:53+01:00
summary:
[3.11] gh-68163: Correct conversion of Rational instances to float (GH-25619) (#96556)
Co-authored-by: Mark Dickinson <dickinsm at gmail.com>
Co-authored-by: Sergey B Kirpichev <skirpichev at gmail.com>
files:
A Misc/NEWS.d/next/Library/2022-09-04-12-32-52.gh-issue-68163.h6TJCc.rst
M Doc/library/numbers.rst
M Lib/numbers.py
M Lib/test/test_numeric_tower.py
diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst
index b12f82ed75a6..b3dce151aee2 100644
--- a/Doc/library/numbers.rst
+++ b/Doc/library/numbers.rst
@@ -58,11 +58,14 @@ The numeric tower
 
 .. class:: Rational
 
- Subtypes :class:`Real` and adds
- :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which
- should be in lowest terms. With these, it provides a default for
+ Subtypes :class:`Real` and adds :attr:`~Rational.numerator` and
+ :attr:`~Rational.denominator` properties. It also provides a default for
 :func:`float`.
 
+ The :attr:`~Rational.numerator` and :attr:`~Rational.denominator` values
+ should be instances of :class:`Integral` and should be in lowest terms with
+ :attr:`~Rational.denominator` positive.
+
 .. attribute:: numerator
 
 Abstract.
diff --git a/Lib/numbers.py b/Lib/numbers.py
index 5b98e642083b..0985dd85f60a 100644
--- a/Lib/numbers.py
+++ b/Lib/numbers.py
@@ -288,7 +288,7 @@ def __float__(self):
 so that ratios of huge integers convert without overflowing.
 
 """
- return self.numerator / self.denominator
+ return int(self.numerator) / int(self.denominator)
 
 
 class Integral(Rational):
diff --git a/Lib/test/test_numeric_tower.py b/Lib/test/test_numeric_tower.py
index c54dedb8b793..9cd85e13634c 100644
--- a/Lib/test/test_numeric_tower.py
+++ b/Lib/test/test_numeric_tower.py
@@ -14,6 +14,27 @@
 _PyHASH_MODULUS = sys.hash_info.modulus
 _PyHASH_INF = sys.hash_info.inf
 
+
+class DummyIntegral(int):
+ """Dummy Integral class to test conversion of the Rational to float."""
+
+ def __mul__(self, other):
+ return DummyIntegral(super().__mul__(other))
+ __rmul__ = __mul__
+
+ def __truediv__(self, other):
+ return NotImplemented
+ __rtruediv__ = __truediv__
+
+ @property
+ def numerator(self):
+ return DummyIntegral(self)
+
+ @property
+ def denominator(self):
+ return DummyIntegral(1)
+
+
 class HashTest(unittest.TestCase):
 def check_equal_hash(self, x, y):
 # check both that x and y are equal and that their hashes are equal
@@ -121,6 +142,13 @@ def test_fractions(self):
 self.assertEqual(hash(F(7*_PyHASH_MODULUS, 1)), 0)
 self.assertEqual(hash(F(-_PyHASH_MODULUS, 1)), 0)
 
+ # The numbers ABC doesn't enforce that the "true" division
+ # of integers produces a float. This tests that the
+ # Rational.__float__() method has required type conversions.
+ x = F(DummyIntegral(1), DummyIntegral(2), _normalize=False)
+ self.assertRaises(TypeError, lambda: x.numerator/x.denominator)
+ self.assertEqual(float(x), 0.5)
+
 def test_hash_normalization(self):
 # Test for a bug encountered while changing long_hash.
 #
diff --git a/Misc/NEWS.d/next/Library/2022-09-04-12-32-52.gh-issue-68163.h6TJCc.rst b/Misc/NEWS.d/next/Library/2022-09-04-12-32-52.gh-issue-68163.h6TJCc.rst
new file mode 100644
index 000000000000..756f6c9eb9e8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-09-04-12-32-52.gh-issue-68163.h6TJCc.rst
@@ -0,0 +1 @@
+Correct conversion of :class:`numbers.Rational`'s to :class:`float`.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /