summaryrefslogtreecommitdiffstats
path: root/Objects/descrobject.c
diff options
context:
space:
mode:
authorPetr Viktorin <encukou@gmail.com>2020-05-07 13:39:59 (GMT)
committerGitHub <noreply@github.com>2020-05-07 13:39:59 (GMT)
commite1becf46b4e3ba6d7d32ebf4bbd3e0804766a423 (patch)
treebe3fda5019edbdc78e82ee21985ea963686f3eb8 /Objects/descrobject.c
parent4638c6429575bd6de26b12b2af5df74d6568b553 (diff)
downloadcpython-e1becf46b4e3ba6d7d32ebf4bbd3e0804766a423.zip
cpython-e1becf46b4e3ba6d7d32ebf4bbd3e0804766a423.tar.gz
cpython-e1becf46b4e3ba6d7d32ebf4bbd3e0804766a423.tar.bz2
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>
Diffstat (limited to 'Objects/descrobject.c')
-rw-r--r--Objects/descrobject.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 572baa5..c9754a1 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -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 *
@@ -336,6 +352,27 @@ exit:
}
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);