mirror of
https://github.com/python/cpython.git
synced 2025-10-17 20:28:43 +00:00
gh-122943: Rework support of var-positional parameter in Argument Clinic (GH-122945)
Move creation of a tuple for var-positional parameter out of _PyArg_UnpackKeywordsWithVararg(). Merge _PyArg_UnpackKeywordsWithVararg() with _PyArg_UnpackKeywords(). Add a new parameter in _PyArg_UnpackKeywords(). The "parameters" and "converters" attributes of ParseArgsCodeGen no longer contain the var-positional parameter. It is now available as the "varpos" attribute. Optimize code generation for var-positional parameter and reuse the same generating code for functions with and without keyword parameters. Add special converters for var-positional parameter. "tuple" represents it as a Python tuple and "array" represents it as a continuous array of PyObject*. "object" is a temporary alias of "tuple".
This commit is contained in:
parent
09d6f5dc78
commit
1f777396f5
22 changed files with 1597 additions and 662 deletions
|
@ -722,22 +722,23 @@ m_log10(double x)
|
|||
/*[clinic input]
|
||||
math.gcd
|
||||
|
||||
*integers as args: object
|
||||
*integers as args: array
|
||||
|
||||
Greatest Common Divisor.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_gcd_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
||||
/*[clinic end generated code: output=b57687fcf431c1b8 input=94e675b7ceeaf0c9]*/
|
||||
math_gcd_impl(PyObject *module, PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=a26c95907374ffb4 input=ded7f0ea3850c05c]*/
|
||||
{
|
||||
// Fast-path for the common case: gcd(int, int)
|
||||
if (nargs == 2 && PyLong_CheckExact(args[0]) && PyLong_CheckExact(args[1]))
|
||||
if (args_length == 2 && PyLong_CheckExact(args[0]) && PyLong_CheckExact(args[1]))
|
||||
{
|
||||
return _PyLong_GCD(args[0], args[1]);
|
||||
}
|
||||
|
||||
if (nargs == 0) {
|
||||
if (args_length == 0) {
|
||||
return PyLong_FromLong(0);
|
||||
}
|
||||
|
||||
|
@ -745,13 +746,13 @@ math_gcd_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
|||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (nargs == 1) {
|
||||
if (args_length == 1) {
|
||||
Py_SETREF(res, PyNumber_Absolute(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
PyObject *one = _PyLong_GetOne(); // borrowed ref
|
||||
for (Py_ssize_t i = 1; i < nargs; i++) {
|
||||
for (Py_ssize_t i = 1; i < args_length; i++) {
|
||||
PyObject *x = _PyNumber_Index(args[i]);
|
||||
if (x == NULL) {
|
||||
Py_DECREF(res);
|
||||
|
@ -804,32 +805,33 @@ long_lcm(PyObject *a, PyObject *b)
|
|||
/*[clinic input]
|
||||
math.lcm
|
||||
|
||||
*integers as args: object
|
||||
*integers as args: array
|
||||
|
||||
Least Common Multiple.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_lcm_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
||||
/*[clinic end generated code: output=f3eff0c25e4d7030 input=e64c33e85f4c47c6]*/
|
||||
math_lcm_impl(PyObject *module, PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=c8a59a5c2e55c816 input=3e4f4b7cdf948a98]*/
|
||||
{
|
||||
PyObject *res, *x;
|
||||
Py_ssize_t i;
|
||||
|
||||
if (nargs == 0) {
|
||||
if (args_length == 0) {
|
||||
return PyLong_FromLong(1);
|
||||
}
|
||||
res = PyNumber_Index(args[0]);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (nargs == 1) {
|
||||
if (args_length == 1) {
|
||||
Py_SETREF(res, PyNumber_Absolute(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
PyObject *zero = _PyLong_GetZero(); // borrowed ref
|
||||
for (i = 1; i < nargs; i++) {
|
||||
for (i = 1; i < args_length; i++) {
|
||||
x = PyNumber_Index(args[i]);
|
||||
if (x == NULL) {
|
||||
Py_DECREF(res);
|
||||
|
@ -2629,7 +2631,7 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q)
|
|||
/*[clinic input]
|
||||
math.hypot
|
||||
|
||||
*coordinates as args: object
|
||||
*coordinates as args: array
|
||||
|
||||
Multidimensional Euclidean distance from the origin to a point.
|
||||
|
||||
|
@ -2646,8 +2648,9 @@ For example, the hypotenuse of a 3/4/5 right triangle is:
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_hypot_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
||||
/*[clinic end generated code: output=dcb6d4b7a1102ee1 input=5c0061a2d11235ed]*/
|
||||
math_hypot_impl(PyObject *module, PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=c9de404e24370068 input=1bceaf7d4fdcd9c2]*/
|
||||
{
|
||||
Py_ssize_t i;
|
||||
PyObject *item;
|
||||
|
@ -2657,13 +2660,13 @@ math_hypot_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
|||
double coord_on_stack[NUM_STACK_ELEMS];
|
||||
double *coordinates = coord_on_stack;
|
||||
|
||||
if (nargs > NUM_STACK_ELEMS) {
|
||||
coordinates = (double *) PyMem_Malloc(nargs * sizeof(double));
|
||||
if (args_length > NUM_STACK_ELEMS) {
|
||||
coordinates = (double *) PyMem_Malloc(args_length * sizeof(double));
|
||||
if (coordinates == NULL) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nargs; i++) {
|
||||
for (i = 0; i < args_length; i++) {
|
||||
item = args[i];
|
||||
ASSIGN_DOUBLE(x, item, error_exit);
|
||||
x = fabs(x);
|
||||
|
@ -2673,7 +2676,7 @@ math_hypot_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
|||
max = x;
|
||||
}
|
||||
}
|
||||
result = vector_norm(nargs, coordinates, max, found_nan);
|
||||
result = vector_norm(args_length, coordinates, max, found_nan);
|
||||
if (coordinates != coord_on_stack) {
|
||||
PyMem_Free(coordinates);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue