summaryrefslogtreecommitdiffstats
path: root/Modules/clinic
diff options
context:
space:
mode:
authorMatthias Görgens <matthias.goergens@gmail.com>2023-05-19 20:03:49 (GMT)
committerGitHub <noreply@github.com>2023-05-19 20:03:49 (GMT)
commit6e39fa19555043588910d10f1fe677cf6b04d77e (patch)
tree04f9df16fd8871323c195e79f2afc251c2882410 /Modules/clinic
parentc3f43bfb4bec39ff8f2c36d861a3c3a243bcb3af (diff)
downloadcpython-6e39fa19555043588910d10f1fe677cf6b04d77e.zip
cpython-6e39fa19555043588910d10f1fe677cf6b04d77e.tar.gz
cpython-6e39fa19555043588910d10f1fe677cf6b04d77e.tar.bz2
gh-94906: Support multiple steps in math.nextafter (#103881)
This PR updates `math.nextafter` to add a new `steps` argument. The behaviour is as though `math.nextafter` had been called `steps` times in succession. --------- Co-authored-by: Mark Dickinson <mdickinson@enthought.com>
Diffstat (limited to 'Modules/clinic')
-rw-r--r--Modules/clinic/mathmodule.c.h55
1 files changed, 47 insertions, 8 deletions
diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h
index bc5bbce..c16c1b0 100644
--- a/Modules/clinic/mathmodule.c.h
+++ b/Modules/clinic/mathmodule.c.h
@@ -826,25 +826,59 @@ exit:
}
PyDoc_STRVAR(math_nextafter__doc__,
-"nextafter($module, x, y, /)\n"
+"nextafter($module, x, y, /, *, steps=None)\n"
"--\n"
"\n"
-"Return the next floating-point value after x towards y.");
+"Return the floating-point value the given number of steps after x towards y.\n"
+"\n"
+"If steps is not specified or is None, it defaults to 1.\n"
+"\n"
+"Raises a TypeError, if x or y is not a double, or if steps is not an integer.\n"
+"Raises ValueError if steps is negative.");
#define MATH_NEXTAFTER_METHODDEF \
- {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL, math_nextafter__doc__},
+ {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL|METH_KEYWORDS, math_nextafter__doc__},
static PyObject *
-math_nextafter_impl(PyObject *module, double x, double y);
+math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps);
static PyObject *
-math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 1
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(steps), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"", "", "steps", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "nextafter",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[3];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
double x;
double y;
+ PyObject *steps = Py_None;
- if (!_PyArg_CheckPositional("nextafter", nargs, 2, 2)) {
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
+ if (!args) {
goto exit;
}
if (PyFloat_CheckExact(args[0])) {
@@ -867,7 +901,12 @@ math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
goto exit;
}
}
- return_value = math_nextafter_impl(module, x, y);
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ steps = args[2];
+skip_optional_kwonly:
+ return_value = math_nextafter_impl(module, x, y, steps);
exit:
return return_value;
@@ -911,4 +950,4 @@ math_ulp(PyObject *module, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=a6437a3ba18c486a input=a9049054013a1b77]*/
+/*[clinic end generated code: output=91a0357265a2a553 input=a9049054013a1b77]*/