Feature or enhancement
A huge part of the CPython code base uses Argument Clinic for generating methods for classes or standalone functions. Generally, methods are then used as follows:
staticPyMethodDeffoo_methods[] = {
_FOOMODULE_FOO_BAR_METHODDEF
{NULL, NULL}
};where each <MODULE>_<CLASS>_<METHOD>_METHODDEF is something like
PyDoc_STRVAR(_foomodule_Foo_bar__doc__,
"bar($self, /)\n""--\n""\n");
#define_FOOMODULE_FOO_BAR_METHODDEF \
{ \
"bar", \
(PyCFunction)_foomodule_Foo_bar, \
METH_NOARGS, \
_foomodule_Foo_bar__doc__ \
},We also have
// @file Modules/foomodule.c/*[clinic input]_foomodule.Foo.bar[clinic start generated code]*/staticPyObject*_foomodule_Foo_bar_impl(FooObject*self)
/*[clinic end generated code: output=... input=...]*/
{
Py_RETURN_NONE;
}
// @file Modules/clinic/foomodule.c.hstaticPyObject*_foomodule_Foo_bar_impl(FooObject*self);
staticPyObject*_foomodule_Foo_bar(FooObject*self, PyObject*Py_UNUSED(ignored))
{
return_foomodule_Foo_bar_impl(self);
}Now, in order to fix #111178, we generally convert non-AC clinic methods by changing FooObject * to PyObject * and doing a pointer cast in the function body. See #111178 for a wider discussion. The issue is that we cannot easily do the same for AC-generated code since the prototype is part of the auto-generated block.
We can do it if we specify self: self(type="PyObject *") instead of not specifying self in the AC input, but this is an overkill. Instead, AC should always generate two functions: an implementation function which takes a typed object (i.e., FooObject) and a public dispatcher which takes a PyObject *self and possibly unused arguments. Stated otherwise:
static PyObject *
-_foomodule_Foo_bar(FooObject *self, PyObject *Py_UNUSED(ignored))+_foomodule_Foo_bar(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- return _foomodule_Foo_bar_impl(self);+ return _foomodule_Foo_bar_impl((FooObject *)self);
}I decided to open a separate issue to track this change orthogonally to the UBSan failures fixes that can be achieved without any AC changes. I hope that this will not deterioriate the performances of CPython too much.
Note: this does not only affect methods as above; this affects any method that is casted to PyCFunction or anything else with incompatible function pointer signatures.
Feature or enhancement
A huge part of the CPython code base uses Argument Clinic for generating methods for classes or standalone functions. Generally, methods are then used as follows:
where each
<MODULE>_<CLASS>_<METHOD>_METHODDEFis something likeWe also have
Now, in order to fix #111178, we generally convert non-AC clinic methods by changing
FooObject *toPyObject *and doing a pointer cast in the function body. See #111178 for a wider discussion. The issue is that we cannot easily do the same for AC-generated code since the prototype is part of the auto-generated block.We can do it if we specify
self: self(type="PyObject *")instead of not specifyingselfin the AC input, but this is an overkill. Instead, AC should always generate two functions: an implementation function which takes a typed object (i.e., FooObject) and a public dispatcher which takes a PyObject *self and possibly unused arguments. Stated otherwise:I decided to open a separate issue to track this change orthogonally to the UBSan failures fixes that can be achieved without any AC changes. I hope that this will not deterioriate the performances of CPython too much.
Note: this does not only affect methods as above; this affects any method that is casted to
PyCFunctionor anything else with incompatible function pointer signatures.