From 2ffe808a7b618019db8bf51ca8ee8d8298e4e5b6 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Wed, 18 Jan 2023 12:22:28 +0300 Subject: [PATCH 1/2] gh-101123: Add signature for the math.hypot --- ...-01-18-12-22-14.gh-issue-101123.ruRJm6.rst | 1 + Modules/clinic/mathmodule.c.h | 48 +++++++++++++++++- Modules/mathmodule.c | 49 +++++++++++-------- 3 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-01-18-12-22-14.gh-issue-101123.ruRJm6.rst diff --git a/Misc/NEWS.d/next/Library/2023-01-18-12-22-14.gh-issue-101123.ruRJm6.rst b/Misc/NEWS.d/next/Library/2023-01-18-12-22-14.gh-issue-101123.ruRJm6.rst new file mode 100644 index 00000000000000..a4a46b52f233f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-18-12-22-14.gh-issue-101123.ruRJm6.rst @@ -0,0 +1 @@ +Add signature for the :func:`~math.typot`. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 1f9725883b9820..fbcc89fdcc712f 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -333,6 +333,52 @@ math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } +PyDoc_STRVAR(math_hypot__doc__, +"hypot($module, /, *coordinates)\n" +"--\n" +"\n" +"Multidimensional Euclidean distance from the origin to a point.\n" +"\n" +"Roughly equivalent to:\n" +" sqrt(sum(x**2 for x in coordinates))\n" +"\n" +"For a two dimensional point (x, y), gives the hypotenuse\n" +"using the Pythagorean theorem: sqrt(x*x + y*y).\n" +"\n" +"For example, the hypotenuse of a 3/4/5 right triangle is:\n" +"\n" +" >>> hypot(3.0, 4.0)\n" +" 5.0"); + +#define MATH_HYPOT_METHODDEF \ + {"hypot", _PyCFunction_CAST(math_hypot), METH_FASTCALL, math_hypot__doc__}, + +static PyObject * +math_hypot_impl(PyObject *module, PyObject *args); + +static PyObject * +math_hypot(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *__clinic_args = NULL; + + if (!_PyArg_CheckPositional("hypot", nargs, 0, PY_SSIZE_T_MAX)) { + goto exit; + } + __clinic_args = PyTuple_New(nargs - 0); + if (!__clinic_args) { + goto exit; + } + for (Py_ssize_t i = 0; i < nargs - 0; ++i) { + PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); + } + return_value = math_hypot_impl(module, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + PyDoc_STRVAR(math_sumprod__doc__, "sumprod($module, p, q, /)\n" "--\n" @@ -954,4 +1000,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=899211ec70e4506c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9dec5aa0e8febbff input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 1342162fa74be7..9f37d681b231e7 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2761,11 +2761,32 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) return NULL; } -/* AC: cannot convert yet, waiting for *args support */ + +/*[clinic input] +math.hypot + + *coordinates as args: object + +Multidimensional Euclidean distance from the origin to a point. + +Roughly equivalent to: + sqrt(sum(x**2 for x in coordinates)) + +For a two dimensional point (x, y), gives the hypotenuse +using the Pythagorean theorem: sqrt(x*x + y*y). + +For example, the hypotenuse of a 3/4/5 right triangle is: + + >>> hypot(3.0, 4.0) + 5.0 + +[clinic start generated code]*/ + static PyObject * -math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +math_hypot_impl(PyObject *module, PyObject *args) +/*[clinic end generated code: output=ace3a23188b6798e input=ff33f88cd8b1f06d]*/ { - Py_ssize_t i; + Py_ssize_t i, nargs; PyObject *item; double max = 0.0; double x, result; @@ -2773,6 +2794,8 @@ math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) double coord_on_stack[NUM_STACK_ELEMS]; double *coordinates = coord_on_stack; + nargs = PyTuple_GET_SIZE(args); + if (nargs > NUM_STACK_ELEMS) { coordinates = (double *) PyObject_Malloc(nargs * sizeof(double)); if (coordinates == NULL) { @@ -2780,7 +2803,7 @@ math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } } for (i = 0; i < nargs; i++) { - item = args[i]; + item = PyTuple_GetItem(args, i); ASSIGN_DOUBLE(x, item, error_exit); x = fabs(x); coordinates[i] = x; @@ -2804,22 +2827,6 @@ math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) #undef NUM_STACK_ELEMS -PyDoc_STRVAR(math_hypot_doc, - "hypot(*coordinates) -> value\n\n\ -Multidimensional Euclidean distance from the origin to a point.\n\ -\n\ -Roughly equivalent to:\n\ - sqrt(sum(x**2 for x in coordinates))\n\ -\n\ -For a two dimensional point (x, y), gives the hypotenuse\n\ -using the Pythagorean theorem: sqrt(x*x + y*y).\n\ -\n\ -For example, the hypotenuse of a 3/4/5 right triangle is:\n\ -\n\ - >>> hypot(3.0, 4.0)\n\ - 5.0\n\ -"); - /** sumprod() ***************************************************************/ /* Forward declaration */ @@ -4234,6 +4241,7 @@ static PyMethodDef math_methods[] = { {"cosh", math_cosh, METH_O, math_cosh_doc}, MATH_DEGREES_METHODDEF MATH_DIST_METHODDEF + MATH_HYPOT_METHODDEF {"erf", math_erf, METH_O, math_erf_doc}, {"erfc", math_erfc, METH_O, math_erfc_doc}, {"exp", math_exp, METH_O, math_exp_doc}, @@ -4247,7 +4255,6 @@ static PyMethodDef math_methods[] = { MATH_FSUM_METHODDEF {"gamma", math_gamma, METH_O, math_gamma_doc}, {"gcd", _PyCFunction_CAST(math_gcd), METH_FASTCALL, math_gcd_doc}, - {"hypot", _PyCFunction_CAST(math_hypot), METH_FASTCALL, math_hypot_doc}, MATH_ISCLOSE_METHODDEF MATH_ISFINITE_METHODDEF MATH_ISINF_METHODDEF From 5d035d7d4c07ff0569965443dc339c9a84f0999c Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Wed, 18 Jan 2023 14:07:01 +0300 Subject: [PATCH 2/2] revert AC stuff & use solution from the issue description (no performance penalty) --- Modules/clinic/mathmodule.c.h | 48 +-------------------------------- Modules/mathmodule.c | 51 ++++++++++++++++------------------- 2 files changed, 24 insertions(+), 75 deletions(-) diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index fbcc89fdcc712f..1f9725883b9820 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -333,52 +333,6 @@ math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -PyDoc_STRVAR(math_hypot__doc__, -"hypot($module, /, *coordinates)\n" -"--\n" -"\n" -"Multidimensional Euclidean distance from the origin to a point.\n" -"\n" -"Roughly equivalent to:\n" -" sqrt(sum(x**2 for x in coordinates))\n" -"\n" -"For a two dimensional point (x, y), gives the hypotenuse\n" -"using the Pythagorean theorem: sqrt(x*x + y*y).\n" -"\n" -"For example, the hypotenuse of a 3/4/5 right triangle is:\n" -"\n" -" >>> hypot(3.0, 4.0)\n" -" 5.0"); - -#define MATH_HYPOT_METHODDEF \ - {"hypot", _PyCFunction_CAST(math_hypot), METH_FASTCALL, math_hypot__doc__}, - -static PyObject * -math_hypot_impl(PyObject *module, PyObject *args); - -static PyObject * -math_hypot(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; - - if (!_PyArg_CheckPositional("hypot", nargs, 0, PY_SSIZE_T_MAX)) { - goto exit; - } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = math_hypot_impl(module, __clinic_args); - -exit: - Py_XDECREF(__clinic_args); - return return_value; -} - PyDoc_STRVAR(math_sumprod__doc__, "sumprod($module, p, q, /)\n" "--\n" @@ -1000,4 +954,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9dec5aa0e8febbff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=899211ec70e4506c input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 9f37d681b231e7..0e610eb9cb1977 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2761,32 +2761,11 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) return NULL; } - -/*[clinic input] -math.hypot - - *coordinates as args: object - -Multidimensional Euclidean distance from the origin to a point. - -Roughly equivalent to: - sqrt(sum(x**2 for x in coordinates)) - -For a two dimensional point (x, y), gives the hypotenuse -using the Pythagorean theorem: sqrt(x*x + y*y). - -For example, the hypotenuse of a 3/4/5 right triangle is: - - >>> hypot(3.0, 4.0) - 5.0 - -[clinic start generated code]*/ - +/* AC: cannot convert yet, waiting for *args support */ static PyObject * -math_hypot_impl(PyObject *module, PyObject *args) -/*[clinic end generated code: output=ace3a23188b6798e input=ff33f88cd8b1f06d]*/ +math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { - Py_ssize_t i, nargs; + Py_ssize_t i; PyObject *item; double max = 0.0; double x, result; @@ -2794,8 +2773,6 @@ math_hypot_impl(PyObject *module, PyObject *args) double coord_on_stack[NUM_STACK_ELEMS]; double *coordinates = coord_on_stack; - nargs = PyTuple_GET_SIZE(args); - if (nargs > NUM_STACK_ELEMS) { coordinates = (double *) PyObject_Malloc(nargs * sizeof(double)); if (coordinates == NULL) { @@ -2803,7 +2780,7 @@ math_hypot_impl(PyObject *module, PyObject *args) } } for (i = 0; i < nargs; i++) { - item = PyTuple_GetItem(args, i); + item = args[i]; ASSIGN_DOUBLE(x, item, error_exit); x = fabs(x); coordinates[i] = x; @@ -2827,6 +2804,24 @@ math_hypot_impl(PyObject *module, PyObject *args) #undef NUM_STACK_ELEMS +PyDoc_STRVAR(math_hypot_doc, + "hypot($module, *coordinates)\n\ +--\n\ +\n\ +Multidimensional Euclidean distance from the origin to a point.\n\ +\n\ +Roughly equivalent to:\n\ + sqrt(sum(x**2 for x in coordinates))\n\ +\n\ +For a two dimensional point (x, y), gives the hypotenuse\n\ +using the Pythagorean theorem: sqrt(x*x + y*y).\n\ +\n\ +For example, the hypotenuse of a 3/4/5 right triangle is:\n\ +\n\ + >>> hypot(3.0, 4.0)\n\ + 5.0\n\ +"); + /** sumprod() ***************************************************************/ /* Forward declaration */ @@ -4241,7 +4236,6 @@ static PyMethodDef math_methods[] = { {"cosh", math_cosh, METH_O, math_cosh_doc}, MATH_DEGREES_METHODDEF MATH_DIST_METHODDEF - MATH_HYPOT_METHODDEF {"erf", math_erf, METH_O, math_erf_doc}, {"erfc", math_erfc, METH_O, math_erfc_doc}, {"exp", math_exp, METH_O, math_exp_doc}, @@ -4255,6 +4249,7 @@ static PyMethodDef math_methods[] = { MATH_FSUM_METHODDEF {"gamma", math_gamma, METH_O, math_gamma_doc}, {"gcd", _PyCFunction_CAST(math_gcd), METH_FASTCALL, math_gcd_doc}, + {"hypot", _PyCFunction_CAST(math_hypot), METH_FASTCALL, math_hypot_doc}, MATH_ISCLOSE_METHODDEF MATH_ISFINITE_METHODDEF MATH_ISINF_METHODDEF