[Python-checkins] bpo-37942: Improve argument clinic float converter (GH-15470)

Raymond Hettinger webhook-mailer at python.org
Sat Aug 24 22:10:43 EDT 2019


https://github.com/python/cpython/commit/aef9ad82f7f667cd001a7112d3bc636e918626f7
commit: aef9ad82f7f667cd001a7112d3bc636e918626f7
branch: master
author: Raymond Hettinger <rhettinger at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019-08-24T19:10:39-07:00
summary:

bpo-37942: Improve argument clinic float converter (GH-15470)

files:
A Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst
M Lib/test/clinic.test
M Modules/clinic/_ssl.c.h
M Modules/clinic/_statisticsmodule.c.h
M Modules/clinic/audioop.c.h
M Modules/clinic/cmathmodule.c.h
M Modules/clinic/mathmodule.c.h
M Python/clinic/sysmodule.c.h
M Python/getargs.c
M Tools/clinic/clinic.py

diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test
index 62c2f00c6b2b..ac6f419c0d3a 100644
--- a/Lib/test/clinic.test
+++ b/Lib/test/clinic.test
@@ -1587,9 +1587,15 @@ test_float_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (nargs < 1) {
         goto skip_optional;
     }
-    a = (float) PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        a = (float) (PyFloat_AS_DOUBLE(args[0]));
+    }
+    else
+    {
+        a = (float) PyFloat_AsDouble(args[0]);
+        if (a == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
 skip_optional:
     return_value = test_float_converter_impl(module, a);
@@ -1600,7 +1606,7 @@ exit:
 
 static PyObject *
 test_float_converter_impl(PyObject *module, float a)
-/*[clinic end generated code: output=8293566b2ec1fc52 input=259c0d98eca35034]*/
+/*[clinic end generated code: output=6b9c7443d2601cea input=259c0d98eca35034]*/
 
 
 /*[clinic input]
@@ -1634,9 +1640,15 @@ test_double_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (nargs < 1) {
         goto skip_optional;
     }
-    a = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        a = PyFloat_AS_DOUBLE(args[0]);
+    }
+    else
+    {
+        a = PyFloat_AsDouble(args[0]);
+        if (a == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
 skip_optional:
     return_value = test_double_converter_impl(module, a);
@@ -1647,7 +1659,7 @@ exit:
 
 static PyObject *
 test_double_converter_impl(PyObject *module, double a)
-/*[clinic end generated code: output=487081a9b8da67ab input=c6a9945706a41c27]*/
+/*[clinic end generated code: output=5b7b9a0f0791b2cc input=c6a9945706a41c27]*/
 
 
 /*[clinic input]
diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst b/Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst
new file mode 100644
index 000000000000..6f6431409554
--- /dev/null
+++ b/Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst
@@ -0,0 +1 @@
+Improve ArgumentClinic converter for floats.
diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h
index b1012f7aee2e..adef7dbf90ce 100644
--- a/Modules/clinic/_ssl.c.h
+++ b/Modules/clinic/_ssl.c.h
@@ -1093,9 +1093,15 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
             goto exit;
         }
     }
-    entropy = PyFloat_AsDouble(args[1]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[1])) {
+        entropy = PyFloat_AS_DOUBLE(args[1]);
+    }
+    else
+    {
+        entropy = PyFloat_AsDouble(args[1]);
+        if (entropy == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = _ssl_RAND_add_impl(module, &view, entropy);
 
@@ -1476,4 +1482,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
 #ifndef _SSL_ENUM_CRLS_METHODDEF
     #define _SSL_ENUM_CRLS_METHODDEF
 #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
-/*[clinic end generated code: output=a399d0eb393b6fab input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5003112e167cd948 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h
index f5a2e4678f30..5ff01efddcde 100644
--- a/Modules/clinic/_statisticsmodule.c.h
+++ b/Modules/clinic/_statisticsmodule.c.h
@@ -26,17 +26,35 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi
     if (!_PyArg_CheckPositional("_normal_dist_inv_cdf", nargs, 3, 3)) {
         goto exit;
     }
-    p = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        p = PyFloat_AS_DOUBLE(args[0]);
     }
-    mu = PyFloat_AsDouble(args[1]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        p = PyFloat_AsDouble(args[0]);
+        if (p == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
-    sigma = PyFloat_AsDouble(args[2]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[1])) {
+        mu = PyFloat_AS_DOUBLE(args[1]);
+    }
+    else
+    {
+        mu = PyFloat_AsDouble(args[1]);
+        if (mu == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[2])) {
+        sigma = PyFloat_AS_DOUBLE(args[2]);
+    }
+    else
+    {
+        sigma = PyFloat_AsDouble(args[2]);
+        if (sigma == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     _return_value = _statistics__normal_dist_inv_cdf_impl(module, p, mu, sigma);
     if ((_return_value == -1.0) && PyErr_Occurred()) {
@@ -47,4 +65,4 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=ba6af124acd34732 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=c5826928a238326c input=a9049054013a1b77]*/
diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h
index 4ea7155373be..aa176964b0f3 100644
--- a/Modules/clinic/audioop.c.h
+++ b/Modules/clinic/audioop.c.h
@@ -615,9 +615,15 @@ audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (width == -1 && PyErr_Occurred()) {
         goto exit;
     }
-    factor = PyFloat_AsDouble(args[2]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[2])) {
+        factor = PyFloat_AS_DOUBLE(args[2]);
+    }
+    else
+    {
+        factor = PyFloat_AsDouble(args[2]);
+        if (factor == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = audioop_mul_impl(module, &fragment, width, factor);
 
@@ -671,13 +677,25 @@ audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (width == -1 && PyErr_Occurred()) {
         goto exit;
     }
-    lfactor = PyFloat_AsDouble(args[2]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[2])) {
+        lfactor = PyFloat_AS_DOUBLE(args[2]);
     }
-    rfactor = PyFloat_AsDouble(args[3]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        lfactor = PyFloat_AsDouble(args[2]);
+        if (lfactor == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[3])) {
+        rfactor = PyFloat_AS_DOUBLE(args[3]);
+    }
+    else
+    {
+        rfactor = PyFloat_AsDouble(args[3]);
+        if (rfactor == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor);
 
@@ -731,13 +749,25 @@ audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (width == -1 && PyErr_Occurred()) {
         goto exit;
     }
-    lfactor = PyFloat_AsDouble(args[2]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[2])) {
+        lfactor = PyFloat_AS_DOUBLE(args[2]);
     }
-    rfactor = PyFloat_AsDouble(args[3]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        lfactor = PyFloat_AsDouble(args[2]);
+        if (lfactor == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[3])) {
+        rfactor = PyFloat_AS_DOUBLE(args[3]);
+    }
+    else
+    {
+        rfactor = PyFloat_AsDouble(args[3]);
+        if (rfactor == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor);
 
@@ -1439,4 +1469,4 @@ audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 
     return return_value;
 }
-/*[clinic end generated code: output=2b173a25726252e9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=af32f4bce9c934fa input=a9049054013a1b77]*/
diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h
index 83c498c22406..33509872069f 100644
--- a/Modules/clinic/cmathmodule.c.h
+++ b/Modules/clinic/cmathmodule.c.h
@@ -766,13 +766,25 @@ cmath_rect(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("rect", nargs, 2, 2)) {
         goto exit;
     }
-    r = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        r = PyFloat_AS_DOUBLE(args[0]);
     }
-    phi = PyFloat_AsDouble(args[1]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        r = PyFloat_AsDouble(args[0]);
+        if (r == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[1])) {
+        phi = PyFloat_AS_DOUBLE(args[1]);
+    }
+    else
+    {
+        phi = PyFloat_AsDouble(args[1]);
+        if (phi == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = cmath_rect_impl(module, r, phi);
 
@@ -922,17 +934,29 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
         goto skip_optional_kwonly;
     }
     if (args[2]) {
-        rel_tol = PyFloat_AsDouble(args[2]);
-        if (PyErr_Occurred()) {
-            goto exit;
+        if (PyFloat_CheckExact(args[2])) {
+            rel_tol = PyFloat_AS_DOUBLE(args[2]);
+        }
+        else
+        {
+            rel_tol = PyFloat_AsDouble(args[2]);
+            if (rel_tol == -1.0 && PyErr_Occurred()) {
+                goto exit;
+            }
         }
         if (!--noptargs) {
             goto skip_optional_kwonly;
         }
     }
-    abs_tol = PyFloat_AsDouble(args[3]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[3])) {
+        abs_tol = PyFloat_AS_DOUBLE(args[3]);
+    }
+    else
+    {
+        abs_tol = PyFloat_AsDouble(args[3]);
+        if (abs_tol == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
 skip_optional_kwonly:
     _return_value = cmath_isclose_impl(module, a, b, rel_tol, abs_tol);
@@ -944,4 +968,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=c7afb866e593fa45 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3ab228947d1709cc input=a9049054013a1b77]*/
diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h
index 84561b955787..95d68ee55ae5 100644
--- a/Modules/clinic/mathmodule.c.h
+++ b/Modules/clinic/mathmodule.c.h
@@ -117,9 +117,15 @@ math_frexp(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_frexp_impl(module, x);
 
@@ -151,9 +157,15 @@ math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) {
         goto exit;
     }
-    x = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        x = PyFloat_AS_DOUBLE(args[0]);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(args[0]);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     i = args[1];
     return_value = math_ldexp_impl(module, x, i);
@@ -182,9 +194,15 @@ math_modf(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_modf_impl(module, x);
 
@@ -277,13 +295,25 @@ math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
         goto exit;
     }
-    x = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        x = PyFloat_AS_DOUBLE(args[0]);
     }
-    y = PyFloat_AsDouble(args[1]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        x = PyFloat_AsDouble(args[0]);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[1])) {
+        y = PyFloat_AS_DOUBLE(args[1]);
+    }
+    else
+    {
+        y = PyFloat_AsDouble(args[1]);
+        if (y == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_fmod_impl(module, x, y);
 
@@ -349,13 +379,25 @@ math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) {
         goto exit;
     }
-    x = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        x = PyFloat_AS_DOUBLE(args[0]);
     }
-    y = PyFloat_AsDouble(args[1]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        x = PyFloat_AsDouble(args[0]);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[1])) {
+        y = PyFloat_AS_DOUBLE(args[1]);
+    }
+    else
+    {
+        y = PyFloat_AsDouble(args[1]);
+        if (y == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_pow_impl(module, x, y);
 
@@ -381,9 +423,15 @@ math_degrees(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_degrees_impl(module, x);
 
@@ -409,9 +457,15 @@ math_radians(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_radians_impl(module, x);
 
@@ -437,9 +491,15 @@ math_isfinite(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_isfinite_impl(module, x);
 
@@ -465,9 +525,15 @@ math_isnan(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_isnan_impl(module, x);
 
@@ -493,9 +559,15 @@ math_isinf(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double x;
 
-    x = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        x = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        x = PyFloat_AsDouble(arg);
+        if (x == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = math_isinf_impl(module, x);
 
@@ -550,29 +622,53 @@ math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
     if (!args) {
         goto exit;
     }
-    a = PyFloat_AsDouble(args[0]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[0])) {
+        a = PyFloat_AS_DOUBLE(args[0]);
     }
-    b = PyFloat_AsDouble(args[1]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    else
+    {
+        a = PyFloat_AsDouble(args[0]);
+        if (a == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
+    }
+    if (PyFloat_CheckExact(args[1])) {
+        b = PyFloat_AS_DOUBLE(args[1]);
+    }
+    else
+    {
+        b = PyFloat_AsDouble(args[1]);
+        if (b == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     if (!noptargs) {
         goto skip_optional_kwonly;
     }
     if (args[2]) {
-        rel_tol = PyFloat_AsDouble(args[2]);
-        if (PyErr_Occurred()) {
-            goto exit;
+        if (PyFloat_CheckExact(args[2])) {
+            rel_tol = PyFloat_AS_DOUBLE(args[2]);
+        }
+        else
+        {
+            rel_tol = PyFloat_AsDouble(args[2]);
+            if (rel_tol == -1.0 && PyErr_Occurred()) {
+                goto exit;
+            }
         }
         if (!--noptargs) {
             goto skip_optional_kwonly;
         }
     }
-    abs_tol = PyFloat_AsDouble(args[3]);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(args[3])) {
+        abs_tol = PyFloat_AS_DOUBLE(args[3]);
+    }
+    else
+    {
+        abs_tol = PyFloat_AsDouble(args[3]);
+        if (abs_tol == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
 skip_optional_kwonly:
     _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
@@ -712,4 +808,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=f93cfe13ab2fdb4e input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9a2b3dc91eb9aadd input=a9049054013a1b77]*/
diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h
index 1f09e0215a5b..2f3bd146e288 100644
--- a/Python/clinic/sysmodule.c.h
+++ b/Python/clinic/sysmodule.c.h
@@ -306,9 +306,15 @@ sys_setswitchinterval(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     double interval;
 
-    interval = PyFloat_AsDouble(arg);
-    if (PyErr_Occurred()) {
-        goto exit;
+    if (PyFloat_CheckExact(arg)) {
+        interval = PyFloat_AS_DOUBLE(arg);
+    }
+    else
+    {
+        interval = PyFloat_AsDouble(arg);
+        if (interval == -1.0 && PyErr_Occurred()) {
+            goto exit;
+        }
     }
     return_value = sys_setswitchinterval_impl(module, interval);
 
@@ -989,4 +995,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored))
 #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
     #define SYS_GETANDROIDAPILEVEL_METHODDEF
 #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
-/*[clinic end generated code: output=acef77d2bb8f6da9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b26faa0abdd700da input=a9049054013a1b77]*/
diff --git a/Python/getargs.c b/Python/getargs.c
index cdc16d4730b5..fe6474c18112 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -887,7 +887,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     case 'f': {/* float */
         float *p = va_arg(*p_va, float *);
         double dval = PyFloat_AsDouble(arg);
-        if (PyErr_Occurred())
+        if (dval == -1.0 && PyErr_Occurred())
             RETURN_ERR_OCCURRED;
         else
             *p = (float) dval;
@@ -897,7 +897,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     case 'd': {/* double */
         double *p = va_arg(*p_va, double *);
         double dval = PyFloat_AsDouble(arg);
-        if (PyErr_Occurred())
+        if (dval == -1.0 && PyErr_Occurred())
             RETURN_ERR_OCCURRED;
         else
             *p = dval;
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index 9880b3951339..d5863a3effe9 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -3106,9 +3106,15 @@ class float_converter(CConverter):
     def parse_arg(self, argname, argnum):
         if self.format_unit == 'f':
             return """
-                {paramname} = (float) PyFloat_AsDouble({argname});
-                if (PyErr_Occurred()) {{{{
-                    goto exit;
+                if (PyFloat_CheckExact({argname})) {{{{
+                    {paramname} = (float) (PyFloat_AS_DOUBLE({argname}));
+                }}}}
+                else
+                {{{{
+                    {paramname} = (float) PyFloat_AsDouble({argname});
+                    if ({paramname} == -1.0 && PyErr_Occurred()) {{{{
+                        goto exit;
+                    }}}}
                 }}}}
                 """.format(argname=argname, paramname=self.name)
         return super().parse_arg(argname, argnum)
@@ -3122,9 +3128,15 @@ class double_converter(CConverter):
     def parse_arg(self, argname, argnum):
         if self.format_unit == 'd':
             return """
-                {paramname} = PyFloat_AsDouble({argname});
-                if (PyErr_Occurred()) {{{{
-                    goto exit;
+                if (PyFloat_CheckExact({argname})) {{{{
+                    {paramname} = PyFloat_AS_DOUBLE({argname});
+                }}}}
+                else
+                {{{{
+                    {paramname} = PyFloat_AsDouble({argname});
+                    if ({paramname} == -1.0 && PyErr_Occurred()) {{{{
+                        goto exit;
+                    }}}}
                 }}}}
                 """.format(argname=argname, paramname=self.name)
         return super().parse_arg(argname, argnum)



More information about the Python-checkins mailing list