classification
Title: Use of argument clinic like parsing and `METH_FASTCALL` support in extension modules
Type: enhancement Stage:
Components: Argument Clinic Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: larry, seberg
Priority: normal Keywords:

Created on 2020-01-15 21:03 by seberg, last changed 2020-01-15 21:03 by seberg.

Messages (1)
msg360073 - (view) Author: Sebastian Berg (seberg) * Date: 2020-01-15 21:03
This is mainly an information request, so sorry if its a bit besides the point (I do not mind if you just close it). But it seemed a bit too specific to get answers in most places...
In Python you use argument clinic, which supports `METH_FASTCALL`, that seems pretty awesome.

For extension modules, I am not sure that argument clinic is a straight forward choice, since it probably generates code specific to a single Python version and also using, while we need to support multiple versions (including versions that do not support `METH_FASTCALL`.

So the question would be if there is some idea for providing such C-API, or for example exposing `_PyArg_UnpackKeywords` (which is at the heart of kwarg parsing).

My use-case is that some NumPy functions do have a nice speedup when using `METH_FASTCALL` and better argument clinic style faster arg-parsing. Which is why, looking at these things, I practically reimplemented a slightly dumbed down version of `PyArg_ParseTupleAndKeywords` working much like argument clinic (except less smart and only using macros and no code generation).

That seems viable, but also feels a bit wrong, so I am curious if there may be a better solution or whether it would be plausible to expose `_PyArg_UnpackKeywords` to reduce code duplication. (although I suppose due to old python version support that would effectively take years)

For completeness, my code in question is here: https://github.com/numpy/numpy/pull/15269 with the actual usage pattern being:

static PyObject *my_method(PyObject *self, NPY_ARGUMENTS_DEF)
{
    NPY_PREPARE_ARGPARSER;
    PyObject *argument1;
    int argument2 = -1;
    if (!npy_parse_arguments("method", 1, -1, NPY_ARGUMENTS_PASS),
                "argument1", NULL, &argument1,
                "argument2", &PyArray_PythonPyIntFromInt, &argument2,
                NULL, NULL, NULL) {
        return NULL;
    }
}
History
Date User Action Args
2020-01-15 21:03:38sebergcreate