[Python-checkins] bpo-33073: Adding as_integer_ratio to ints. (GH-8750)
Raymond Hettinger
webhook-mailer at python.org
Fri Sep 14 02:56:27 EDT 2018
https://github.com/python/cpython/commit/5ac704306f4b81ae3f28d8742408d3214b145e8a
commit: 5ac704306f4b81ae3f28d8742408d3214b145e8a
branch: master
author: Lisa Roach <lisaroach14 at gmail.com>
committer: Raymond Hettinger <rhettinger at users.noreply.github.com>
date: 2018-09-13T23:56:23-07:00
summary:
bpo-33073: Adding as_integer_ratio to ints. (GH-8750)
files:
A Misc/NEWS.d/next/Core and Builtins/2018-08-12-16-03-58.bpo-33073.XWu1Jh.rst
M Doc/library/stdtypes.rst
M Doc/whatsnew/3.8.rst
M Lib/test/test_doctest.py
M Lib/test/test_long.py
M Misc/ACKS
M Objects/clinic/longobject.c.h
M Objects/longobject.c
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index fd59a5170dae..5a133e32fced 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -537,6 +537,14 @@ class`. In addition, it provides a few more methods:
.. versionadded:: 3.2
+.. method:: int.as_integer_ratio()
+
+ Return a pair of integers whose ratio is exactly equal to the original
+ integer and with a positive denominator. The integer ratio of integers
+ (whole numbers) is always the integer as the numerator and ``1`` as the
+ denominator.
+
+ .. versionadded:: 3.8
Additional Methods on Float
---------------------------
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index b2475c7df33e..38b8623dddd2 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -91,6 +91,10 @@ 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.
+ (Contributed by Lisa Roach in :issue:`33073`.)
+
* Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`.
(Contributed by Jonathan Eunice and Serhiy Storchaka in :issue:`30688`.)
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 83941c129f44..797bdb847190 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -665,7 +665,7 @@ def non_Python_modules(): r"""
True
>>> real_tests = [t for t in tests if len(t.examples) > 0]
>>> len(real_tests) # objects that actually have doctests
- 8
+ 9
>>> for t in real_tests:
... print('{} {}'.format(len(t.examples), t.name))
...
@@ -675,6 +675,7 @@ def non_Python_modules(): r"""
2 builtins.float.hex
1 builtins.hex
1 builtins.int
+ 3 builtins.int.as_integer_ratio
2 builtins.int.bit_length
1 builtins.oct
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index 8472889d48ba..7c883baebb41 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -3,6 +3,7 @@
import sys
+import enum
import random
import math
import array
@@ -1349,6 +1350,37 @@ def test_shift_bool(self):
self.assertEqual(type(value << shift), int)
self.assertEqual(type(value >> shift), int)
+ def test_as_integer_ratio(self):
+ tests = [10, 0, -10, 1]
+ 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)
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/ACKS b/Misc/ACKS
index 96985358e236..a29ff6020bbf 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1350,6 +1350,7 @@ Juan M. Bello Rivas
Mohd Sanad Zaki Rizvi
Davide Rizzo
Anthony Roach
+Lisa Roach
Carl Robben
Ben Roberts
Mark Roberts
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-08-12-16-03-58.bpo-33073.XWu1Jh.rst b/Misc/NEWS.d/next/Core and Builtins/2018-08-12-16-03-58.bpo-33073.XWu1Jh.rst
new file mode 100644
index 000000000000..ce9b6129f96e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-08-12-16-03-58.bpo-33073.XWu1Jh.rst
@@ -0,0 +1 @@
+Added as_integer_ratio to ints to make them more interoperable with floats.
diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h
index 14f5515c7a62..0e70fe5d8c44 100644
--- a/Objects/clinic/longobject.c.h
+++ b/Objects/clinic/longobject.c.h
@@ -118,6 +118,34 @@ int_bit_length(PyObject *self, PyObject *Py_UNUSED(ignored))
return int_bit_length_impl(self);
}
+PyDoc_STRVAR(int_as_integer_ratio__doc__,
+"as_integer_ratio($self, /)\n"
+"--\n"
+"\n"
+"Return integer ratio.\n"
+"\n"
+"Return a pair of integers, whose ratio is exactly equal to the original int\n"
+"and with a positive denominator.\n"
+"\n"
+">>> (10).as_integer_ratio()\n"
+"(10, 1)\n"
+">>> (-10).as_integer_ratio()\n"
+"(-10, 1)\n"
+">>> (0).as_integer_ratio()\n"
+"(0, 1)");
+
+#define INT_AS_INTEGER_RATIO_METHODDEF \
+ {"as_integer_ratio", (PyCFunction)int_as_integer_ratio, METH_NOARGS, int_as_integer_ratio__doc__},
+
+static PyObject *
+int_as_integer_ratio_impl(PyObject *self);
+
+static PyObject *
+int_as_integer_ratio(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return int_as_integer_ratio_impl(self);
+}
+
PyDoc_STRVAR(int_to_bytes__doc__,
"to_bytes($self, /, length, byteorder, *, signed=False)\n"
"--\n"
@@ -211,4 +239,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb
exit:
return return_value;
}
-/*[clinic end generated code: output=fd64beb83bd16df3 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=6d5e92d7dc803751 input=a9049054013a1b77]*/
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 399d35427099..98ff9a8c265b 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -5260,6 +5260,36 @@ long_is_finite(PyObject *v)
}
#endif
+/*[clinic input]
+int.as_integer_ratio
+
+Return integer ratio.
+
+Return a pair of integers, whose ratio is exactly equal to the original int
+and with a positive denominator.
+
+>>> (10).as_integer_ratio()
+(10, 1)
+>>> (-10).as_integer_ratio()
+(-10, 1)
+>>> (0).as_integer_ratio()
+(0, 1)
+[clinic start generated code]*/
+
+static PyObject *
+int_as_integer_ratio_impl(PyObject *self)
+/*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/
+{
+ if PyLong_CheckExact(self) {
+ return PyTuple_Pack(2, self, _PyLong_One);
+ } else {
+ PyObject *numerator = _PyLong_Copy(self);
+ PyObject *ratio_tuple = PyTuple_Pack(2, numerator, _PyLong_One);
+ Py_DECREF(numerator);
+ return ratio_tuple;
+ }
+}
+
/*[clinic input]
int.to_bytes
@@ -5392,6 +5422,7 @@ static PyMethodDef long_methods[] = {
#endif
INT_TO_BYTES_METHODDEF
INT_FROM_BYTES_METHODDEF
+ INT_AS_INTEGER_RATIO_METHODDEF
{"__trunc__", long_long_meth, METH_NOARGS,
"Truncating an Integral returns itself."},
{"__floor__", long_long_meth, METH_NOARGS,
More information about the Python-checkins
mailing list