[Python-checkins] bpo-41342: Convert int.__round__ to Argument Clinic (GH-21549)

Serhiy Storchaka webhook-mailer at python.org
Mon Jul 20 08:57:41 EDT 2020


https://github.com/python/cpython/commit/5a2bac7fe0e7a2b67fd57c7a9176a50feed0d7a0
commit: 5a2bac7fe0e7a2b67fd57c7a9176a50feed0d7a0
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-07-20T15:57:37+03:00
summary:

bpo-41342: Convert int.__round__ to Argument Clinic (GH-21549)

files:
A Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst
M Objects/clinic/longobject.c.h
M Objects/longobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst b/Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst
new file mode 100644
index 0000000000000..38851a7f7fc0f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-07-19-15-40-52.bpo-41342.RRk_m_.rst	
@@ -0,0 +1 @@
+:func:`round` with integer argument is now faster (9--60%).
diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h
index cf388c50f5a6a..4bd47b116f883 100644
--- a/Objects/clinic/longobject.c.h
+++ b/Objects/clinic/longobject.c.h
@@ -87,6 +87,40 @@ int___format__(PyObject *self, PyObject *arg)
     return return_value;
 }
 
+PyDoc_STRVAR(int___round____doc__,
+"__round__($self, ndigits=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Rounding an Integral returns itself.\n"
+"\n"
+"Rounding with an ndigits argument also returns an integer.");
+
+#define INT___ROUND___METHODDEF    \
+    {"__round__", (PyCFunction)(void(*)(void))int___round__, METH_FASTCALL, int___round____doc__},
+
+static PyObject *
+int___round___impl(PyObject *self, PyObject *o_ndigits);
+
+static PyObject *
+int___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *o_ndigits = NULL;
+
+    if (!_PyArg_CheckPositional("__round__", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    o_ndigits = args[0];
+skip_optional:
+    return_value = int___round___impl(self, o_ndigits);
+
+exit:
+    return return_value;
+}
+
 PyDoc_STRVAR(int___sizeof____doc__,
 "__sizeof__($self, /)\n"
 "--\n"
@@ -333,4 +367,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=4257cfdb155efd00 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=ea18e51af5b53591 input=a9049054013a1b77]*/
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 571f53a3c00eb..92514d4154e2c 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -5155,10 +5155,22 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b)
     return NULL;
 }
 
+/*[clinic input]
+int.__round__
+
+    ndigits as o_ndigits: object = NULL
+    /
+
+Rounding an Integral returns itself.
+
+Rounding with an ndigits argument also returns an integer.
+[clinic start generated code]*/
+
 static PyObject *
-long_round(PyObject *self, PyObject *args)
+int___round___impl(PyObject *self, PyObject *o_ndigits)
+/*[clinic end generated code: output=954fda6b18875998 input=1614cf23ec9e18c3]*/
 {
-    PyObject *o_ndigits=NULL, *temp, *result, *ndigits;
+    PyObject *temp, *result, *ndigits;
 
     /* To round an integer m to the nearest 10**n (n positive), we make use of
      * the divmod_near operation, defined by:
@@ -5174,8 +5186,6 @@ long_round(PyObject *self, PyObject *args)
      *
      *   m - divmod_near(m, 10**n)[1].
      */
-    if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
-        return NULL;
     if (o_ndigits == NULL)
         return long_long(self);
 
@@ -5536,9 +5546,7 @@ static PyMethodDef long_methods[] = {
      "Flooring an Integral returns itself."},
     {"__ceil__",        long_long_meth, METH_NOARGS,
      "Ceiling of an Integral returns itself."},
-    {"__round__",       (PyCFunction)long_round, METH_VARARGS,
-     "Rounding an Integral returns itself.\n"
-     "Rounding with an ndigits argument also returns an integer."},
+    INT___ROUND___METHODDEF
     INT___GETNEWARGS___METHODDEF
     INT___FORMAT___METHODDEF
     INT___SIZEOF___METHODDEF



More information about the Python-checkins mailing list