From 57ad769076201c858a768d81047f6ea44925a33b Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Fri, 7 Jun 2024 11:03:28 +0300 Subject: [PATCH] gh-120080: Accept ``None`` as a valid argument for direct call of the ``int.__round__`` (#120088) Co-authored-by: Nikita Sobolev --- Lib/test/test_float.py | 6 ++++++ Lib/test/test_inspect/test_inspect.py | 1 - Lib/test/test_int.py | 6 ++++++ .../2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst | 2 ++ Objects/clinic/longobject.c.h | 6 +++--- Objects/longobject.c | 6 +++--- 6 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 5bd640617d6..53695cefb8f 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -949,6 +949,12 @@ class RoundTestCase(unittest.TestCase): self.assertEqual(x, 2) self.assertIsInstance(x, int) + def test_round_with_none_arg_direct_call(self): + for val in [(1.0).__round__(None), + round(1.0), + round(1.0, None)]: + self.assertEqual(val, 1) + self.assertIs(type(val), int) # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 011d42f34b6..65007c16203 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -5412,7 +5412,6 @@ class TestSignatureDefinitions(unittest.TestCase): 'bytearray': {'count', 'endswith', 'find', 'hex', 'index', 'rfind', 'rindex', 'startswith'}, 'bytes': {'count', 'endswith', 'find', 'hex', 'index', 'rfind', 'rindex', 'startswith'}, 'dict': {'pop'}, - 'int': {'__round__'}, 'memoryview': {'cast', 'hex'}, 'str': {'count', 'endswith', 'find', 'index', 'maketrans', 'rfind', 'rindex', 'startswith'}, } diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index ce9febd741b..77221dfb6d5 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -517,6 +517,12 @@ class IntTestCases(unittest.TestCase): self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789) self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807) + def test_round_with_none_arg_direct_call(self): + for val in [(1).__round__(None), + round(1), + round(1, None)]: + self.assertEqual(val, 1) + self.assertIs(type(val), int) class IntStrDigitLimitsTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst new file mode 100644 index 00000000000..8c5602fcdb4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-06-05-08-39-40.gh-issue-120080.DJFK11.rst @@ -0,0 +1,2 @@ +Direct call to the :meth:`!int.__round__` now accepts ``None`` +as a valid argument. diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 56bc3864582..90375b9a082 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -116,7 +116,7 @@ exit: } PyDoc_STRVAR(int___round____doc__, -"__round__($self, ndigits=, /)\n" +"__round__($self, ndigits=None, /)\n" "--\n" "\n" "Rounding an Integral returns itself.\n" @@ -133,7 +133,7 @@ static PyObject * int___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *o_ndigits = NULL; + PyObject *o_ndigits = Py_None; if (!_PyArg_CheckPositional("__round__", nargs, 0, 1)) { goto exit; @@ -476,4 +476,4 @@ int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) { return int_is_integer_impl(self); } -/*[clinic end generated code: output=2ba2d8dcda9b99da input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a53f5ba9a6c16737 input=a9049054013a1b77]*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index ee0b2a038a2..a3a59a20f0b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -6045,7 +6045,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) /*[clinic input] int.__round__ - ndigits as o_ndigits: object = NULL + ndigits as o_ndigits: object = None / Rounding an Integral returns itself. @@ -6055,7 +6055,7 @@ Rounding with an ndigits argument also returns an integer. static PyObject * int___round___impl(PyObject *self, PyObject *o_ndigits) -/*[clinic end generated code: output=954fda6b18875998 input=1614cf23ec9e18c3]*/ +/*[clinic end generated code: output=954fda6b18875998 input=30c2aec788263144]*/ { PyObject *temp, *result, *ndigits; @@ -6073,7 +6073,7 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) * * m - divmod_near(m, 10**n)[1]. */ - if (o_ndigits == NULL) + if (o_ndigits == Py_None) return long_long(self); ndigits = _PyNumber_Index(o_ndigits);