bpo-33073: Rework int.as_integer_ratio() implementation (GH-9303)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 19 Oct 2018 21:46:31 +0000 (00:46 +0300)
committerVictor Stinner <vstinner@redhat.com>
Fri, 19 Oct 2018 21:46:31 +0000 (23:46 +0200)
* Simplify the C code.
* Simplify tests and make them more strict and robust.
* Add references in the documentation.

Doc/whatsnew/3.8.rst
Lib/test/test_long.py
Objects/longobject.c

index e522addf391fa56a7fe1d71e83950115a733d28b..93dd24acaa8aaaafa7324de827c3a0609a147e0a 100644 (file)
@@ -91,8 +91,8 @@ Other Language Changes
   was lifted.
   (Contributed by Serhiy Storchaka in :issue:`32489`.)
 
-* The ``int`` type now has a new ``as_integer_ratio`` method compatible
-  with the existing ``float.as_integer_ratio`` method.
+* The :class:`int` type now has a new :meth:`~int.as_integer_ratio` method
+  compatible with the existing :meth:`float.as_integer_ratio` method.
   (Contributed by Lisa Roach in :issue:`33073`.)
 
 * Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`.
index 5b860dd36bc09f4ae94911c307d48c38cc340d24..53101b3badb36d682db79d90bf7aaa1eec2951ce 100644 (file)
@@ -3,7 +3,6 @@ from test import support
 
 import sys
 
-import enum
 import random
 import math
 import array
@@ -1354,35 +1353,14 @@ class LongTest(unittest.TestCase):
                 self.assertEqual(type(value >> shift), int)
 
     def test_as_integer_ratio(self):
-        tests = [10, 0, -10, 1]
+        class myint(int):
+            pass
+        tests = [10, 0, -10, 1, sys.maxsize + 1, True, False, myint(42)]
         for value in tests:
             numerator, denominator = value.as_integer_ratio()
-            self.assertEqual((numerator, denominator), (value, 1))
-            self.assertIsInstance(numerator, int)
-            self.assertIsInstance(denominator, int)
-
-    def test_as_integer_ratio_maxint(self):
-        x = sys.maxsize + 1
-        self.assertEqual(x.as_integer_ratio()[0], x)
-
-    def test_as_integer_ratio_bool(self):
-        self.assertEqual(True.as_integer_ratio(), (1, 1))
-        self.assertEqual(False.as_integer_ratio(), (0, 1))
-        self.assertEqual(type(True.as_integer_ratio()[0]), int)
-        self.assertEqual(type(False.as_integer_ratio()[0]), int)
-
-    def test_as_integer_ratio_int_enum(self):
-        class Foo(enum.IntEnum):
-            X = 42
-        self.assertEqual(Foo.X.as_integer_ratio(), (42, 1))
-        self.assertEqual(type(Foo.X.as_integer_ratio()[0]), int)
-
-    def test_as_integer_ratio_int_flag(self):
-        class Foo(enum.IntFlag):
-            R = 1 << 2
-        self.assertEqual(Foo.R.as_integer_ratio(), (4, 1))
-        self.assertEqual(type(Foo.R.as_integer_ratio()[0]), int)
-
+            self.assertEqual((numerator, denominator), (int(value), 1))
+            self.assertEqual(type(numerator), int)
+            self.assertEqual(type(denominator), int)
 
 
 if __name__ == "__main__":
index ae3a98cc791c9a48e62b9b050c139251154d24f5..6f7fe335d9f2ff12ad8cd91e753e50f38f51e53e 100644 (file)
@@ -5280,13 +5280,8 @@ static PyObject *
 int_as_integer_ratio_impl(PyObject *self)
 /*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/
 {
-    PyObject *numerator;
     PyObject *ratio_tuple;
-
-    if (PyLong_CheckExact(self)) {
-        return PyTuple_Pack(2, self, _PyLong_One);
-    }
-    numerator = _PyLong_Copy((PyLongObject *) self);
+    PyObject *numerator = long_long(self);
     if (numerator == NULL) {
         return NULL;
     }