mirror of
https://github.com/python/cpython.git
synced 2025-12-09 18:48:05 +00:00
bpo-38787: C API for module state access from extension methods (PEP 573) (GH-19936)
Module C state is now accessible from C-defined heap type methods (PEP 573). Patch by Marcel Plch and Petr Viktorin. Co-authored-by: Marcel Plch <mplch@redhat.com> Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
4638c64295
commit
e1becf46b4
19 changed files with 797 additions and 51 deletions
|
|
@ -127,7 +127,11 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
|
|||
((PyTypeObject *)type)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
return PyCFunction_NewEx(descr->d_method, type, NULL);
|
||||
PyTypeObject *cls = NULL;
|
||||
if (descr->d_method->ml_flags & METH_METHOD) {
|
||||
cls = descr->d_common.d_type;
|
||||
}
|
||||
return PyCMethod_New(descr->d_method, type, NULL, cls);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
@ -137,7 +141,19 @@ method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
|
|||
|
||||
if (descr_check((PyDescrObject *)descr, obj, &res))
|
||||
return res;
|
||||
return PyCFunction_NewEx(descr->d_method, obj, NULL);
|
||||
if (descr->d_method->ml_flags & METH_METHOD) {
|
||||
if (PyType_Check(type)) {
|
||||
return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type);
|
||||
} else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"descriptor '%V' needs a type, not '%s', as arg 2",
|
||||
descr_name((PyDescrObject *)descr),
|
||||
Py_TYPE(type)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return PyCFunction_NewEx(descr->d_method, obj, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
@ -335,6 +351,27 @@ exit:
|
|||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
method_vectorcall_FASTCALL_KEYWORDS_METHOD(
|
||||
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
|
||||
if (method_check_args(func, args, nargs, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
NULL;
|
||||
PyCMethod meth = (PyCMethod) method_enter_call(tstate, func);
|
||||
if (meth == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject *result = meth(args[0],
|
||||
((PyMethodDescrObject *)func)->d_common.d_type,
|
||||
args+1, nargs-1, kwnames);
|
||||
Py_LeaveRecursiveCall();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
method_vectorcall_FASTCALL(
|
||||
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
|
|
@ -868,7 +905,8 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
|
|||
{
|
||||
/* Figure out correct vectorcall function to use */
|
||||
vectorcallfunc vectorcall;
|
||||
switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS))
|
||||
switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS |
|
||||
METH_O | METH_KEYWORDS | METH_METHOD))
|
||||
{
|
||||
case METH_VARARGS:
|
||||
vectorcall = method_vectorcall_VARARGS;
|
||||
|
|
@ -888,6 +926,9 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
|
|||
case METH_O:
|
||||
vectorcall = method_vectorcall_O;
|
||||
break;
|
||||
case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
|
||||
vectorcall = method_vectorcall_FASTCALL_KEYWORDS_METHOD;
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"%s() method: bad call flags", method->ml_name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue