diff options
author | Jeroen Demeyer <J.Demeyer@UGent.be> | 2019-06-28 09:49:00 (GMT) |
---|---|---|
committer | Inada Naoki <songofacandy@gmail.com> | 2019-06-28 09:49:00 (GMT) |
commit | b1263d5a60d3f7ab02dd28409fff59b3815a3f67 (patch) | |
tree | d2b48c8ffcf6b8d4c042495e0b8888b7deda086e /Objects/call.c | |
parent | b4bee03087a3c70cb040e2ce569c828860ed8e87 (diff) | |
download | cpython-b1263d5a60d3f7ab02dd28409fff59b3815a3f67.zip cpython-b1263d5a60d3f7ab02dd28409fff59b3815a3f67.tar.gz cpython-b1263d5a60d3f7ab02dd28409fff59b3815a3f67.tar.bz2 |
bpo-37337: Add _PyObject_VectorcallMethod() (GH-14228)
Diffstat (limited to 'Objects/call.c')
-rw-r--r-- | Objects/call.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/Objects/call.c b/Objects/call.c index bde5513..2b52bdf 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1078,6 +1078,38 @@ object_vacall(PyObject *base, PyObject *callable, va_list vargs) PyObject * +_PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + assert(name != NULL); + assert(args != NULL); + assert(PyVectorcall_NARGS(nargsf) >= 1); + + PyObject *callable = NULL; + /* Use args[0] as "self" argument */ + int unbound = _PyObject_GetMethod(args[0], name, &callable); + if (callable == NULL) { + return NULL; + } + + if (unbound) { + /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since + * that would be interpreted as allowing to change args[-1] */ + nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET; + } + else { + /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since + * args[-1] in the onward call is args[0] here. */ + args++; + nargsf--; + } + PyObject *result = _PyObject_Vectorcall(callable, args, nargsf, kwnames); + Py_DECREF(callable); + return result; +} + + +PyObject * PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) { if (obj == NULL || name == NULL) { |