Commit b2e20259 authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by Victor Stinner

bpo-33073: Rework int.as_integer_ratio() implementation (GH-9303)

* Simplify the C code.
* Simplify tests and make them more strict and robust.
* Add references in the documentation.
parent b981fec8
...@@ -91,8 +91,8 @@ Other Language Changes ...@@ -91,8 +91,8 @@ Other Language Changes
was lifted. was lifted.
(Contributed by Serhiy Storchaka in :issue:`32489`.) (Contributed by Serhiy Storchaka in :issue:`32489`.)
* The ``int`` type now has a new ``as_integer_ratio`` method compatible * The :class:`int` type now has a new :meth:`~int.as_integer_ratio` method
with the existing ``float.as_integer_ratio`` method. compatible with the existing :meth:`float.as_integer_ratio` method.
(Contributed by Lisa Roach in :issue:`33073`.) (Contributed by Lisa Roach in :issue:`33073`.)
* Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`. * Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`.
......
...@@ -3,7 +3,6 @@ from test import support ...@@ -3,7 +3,6 @@ from test import support
import sys import sys
import enum
import random import random
import math import math
import array import array
...@@ -1354,35 +1353,14 @@ class LongTest(unittest.TestCase): ...@@ -1354,35 +1353,14 @@ class LongTest(unittest.TestCase):
self.assertEqual(type(value >> shift), int) self.assertEqual(type(value >> shift), int)
def test_as_integer_ratio(self): 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: for value in tests:
numerator, denominator = value.as_integer_ratio() numerator, denominator = value.as_integer_ratio()
self.assertEqual((numerator, denominator), (value, 1)) self.assertEqual((numerator, denominator), (int(value), 1))
self.assertIsInstance(numerator, int) self.assertEqual(type(numerator), int)
self.assertIsInstance(denominator, int) self.assertEqual(type(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)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -5280,13 +5280,8 @@ static PyObject * ...@@ -5280,13 +5280,8 @@ static PyObject *
int_as_integer_ratio_impl(PyObject *self) int_as_integer_ratio_impl(PyObject *self)
/*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/ /*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/
{ {
PyObject *numerator;
PyObject *ratio_tuple; PyObject *ratio_tuple;
PyObject *numerator = long_long(self);
if (PyLong_CheckExact(self)) {
return PyTuple_Pack(2, self, _PyLong_One);
}
numerator = _PyLong_Copy((PyLongObject *) self);
if (numerator == NULL) { if (numerator == NULL) {
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment