bpo-46921: Vectorcall support for `super()` (GH-31687)

Co-Authored-By: Dong-hee Na <donghee.na@python.org>
diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py
index 5d94372..a68b38c 100644
--- a/Lib/test/test_super.py
+++ b/Lib/test/test_super.py
@@ -317,6 +317,14 @@
         for i in range(1000):
             super.__init__(sp, int, i)
 
+    def test_super_argcount(self):
+        with self.assertRaisesRegex(TypeError, "expected at most"):
+            super(int, int, int)
+
+    def test_super_argtype(self):
+        with self.assertRaisesRegex(TypeError, "argument 1 must be a type"):
+            super(1, int)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst
new file mode 100644
index 0000000..4ccd00b
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst
@@ -0,0 +1 @@
+Support vectorcall for ``super()``. Patch by Ken Jin.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 1dfeac3..7879515 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -9000,19 +9000,28 @@
     return 0;
 }
 
+static int super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj);
+
 static int
 super_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    superobject *su = (superobject *)self;
     PyTypeObject *type = NULL;
     PyObject *obj = NULL;
-    PyTypeObject *obj_type = NULL;
 
     if (!_PyArg_NoKeywords("super", kwds))
         return -1;
     if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj))
         return -1;
+    if (super_init_impl(self, type, obj) < 0) {
+        return -1;
+    }
+    return 0;
+}
 
+static inline int
+super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) {
+    superobject *su = (superobject *)self;
+    PyTypeObject *obj_type = NULL;
     if (type == NULL) {
         /* Call super(), without args -- fill in from __class__
            and first local variable on the stack. */
@@ -9072,6 +9081,47 @@
     return 0;
 }
 
+static PyObject *
+super_vectorcall(PyObject *self, PyObject *const *args,
+    size_t nargsf, PyObject *kwnames)
+{
+    assert(PyType_Check(self));
+    if (!_PyArg_NoKwnames("super", kwnames)) {
+        return NULL;
+    }
+    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+    if (!_PyArg_CheckPositional("super()", nargs, 0, 2)) {
+        return NULL;
+    }
+    PyTypeObject *type = NULL;
+    PyObject *obj = NULL;
+    PyTypeObject *self_type = (PyTypeObject *)self;
+    PyObject *su = self_type->tp_alloc(self_type, 0);
+    if (su == NULL) {
+        return NULL;
+    }
+    // 1 or 2 argument form super().
+    if (nargs != 0) {
+        PyObject *arg0 = args[0];
+        if (!PyType_Check(arg0)) {
+            PyErr_Format(PyExc_TypeError,
+                "super() argument 1 must be a type, not %.200s", Py_TYPE(arg0)->tp_name);
+            goto fail;
+        }
+        type = (PyTypeObject *)arg0;
+    }
+    if (nargs == 2) {
+        obj = args[1];
+    }
+    if (super_init_impl(su, type, obj) < 0) {
+        goto fail;
+    }
+    return su;
+fail:
+    Py_DECREF(su);
+    return NULL;
+}
+
 PyTypeObject PySuper_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "super",                                    /* tp_name */
@@ -9114,4 +9164,5 @@
     PyType_GenericAlloc,                        /* tp_alloc */
     PyType_GenericNew,                          /* tp_new */
     PyObject_GC_Del,                            /* tp_free */
+    .tp_vectorcall = (vectorcallfunc)super_vectorcall,
 };