summaryrefslogtreecommitdiffstats
path: root/Objects/call.c
diff options
context:
space:
mode:
authorJeroen Demeyer <J.Demeyer@UGent.be>2019-06-28 09:49:00 (GMT)
committerInada Naoki <songofacandy@gmail.com>2019-06-28 09:49:00 (GMT)
commitb1263d5a60d3f7ab02dd28409fff59b3815a3f67 (patch)
treed2b48c8ffcf6b8d4c042495e0b8888b7deda086e /Objects/call.c
parentb4bee03087a3c70cb040e2ce569c828860ed8e87 (diff)
downloadcpython-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.c32
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) {