mirror of
https://github.com/python/cpython.git
synced 2024-11-27 11:55:13 +08:00
bpo-33073: Adding as_integer_ratio to ints. (GH-8750)
This commit is contained in:
parent
83df50ea57
commit
5ac704306f
@ -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
|
||||
---------------------------
|
||||
|
@ -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`.)
|
||||
|
||||
|
@ -665,7 +665,7 @@ plain ol' Python and is guaranteed to be available.
|
||||
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 @@ plain ol' Python and is guaranteed to be available.
|
||||
2 builtins.float.hex
|
||||
1 builtins.hex
|
||||
1 builtins.int
|
||||
3 builtins.int.as_integer_ratio
|
||||
2 builtins.int.bit_length
|
||||
1 builtins.oct
|
||||
|
||||
|
@ -3,6 +3,7 @@ from test import support
|
||||
|
||||
import sys
|
||||
|
||||
import enum
|
||||
import random
|
||||
import math
|
||||
import array
|
||||
@ -1349,6 +1350,37 @@ class LongTest(unittest.TestCase):
|
||||
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()
|
||||
|
@ -1350,6 +1350,7 @@ Juan M. Bello Rivas
|
||||
Mohd Sanad Zaki Rizvi
|
||||
Davide Rizzo
|
||||
Anthony Roach
|
||||
Lisa Roach
|
||||
Carl Robben
|
||||
Ben Roberts
|
||||
Mark Roberts
|
||||
|
@ -0,0 +1 @@
|
||||
Added as_integer_ratio to ints to make them more interoperable with floats.
|
30
Objects/clinic/longobject.c.h
generated
30
Objects/clinic/longobject.c.h
generated
@ -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]*/
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user