[Python-checkins] bpo-46921: Vectorcall support for `super()` (GH-31687)
Fidget-Spinner
webhook-mailer at python.org
Sun Mar 6 01:22:00 EST 2022
https://github.com/python/cpython/commit/602024e6e12c69d836aa191d63db75862aec2493
commit: 602024e6e12c69d836aa191d63db75862aec2493
branch: main
author: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com>
committer: Fidget-Spinner <28750310+Fidget-Spinner at users.noreply.github.com>
date: 2022-03-06T14:21:28+08:00
summary:
bpo-46921: Vectorcall support for `super()` (GH-31687)
Co-Authored-By: Dong-hee Na <donghee.na at python.org>
files:
A Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst
M Lib/test/test_super.py
M Objects/typeobject.c
diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py
index 5d94372bf6ec7..a68b38cf79d53 100644
--- a/Lib/test/test_super.py
+++ b/Lib/test/test_super.py
@@ -317,6 +317,14 @@ def test_super_init_leaks(self):
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 0000000000000..4ccd00b87f591
--- /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 1dfeac3b9e660..7879515075613 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -9000,19 +9000,28 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co,
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 @@ super_traverse(PyObject *self, visitproc visit, void *arg)
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 @@ PyTypeObject PySuper_Type = {
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
+ .tp_vectorcall = (vectorcallfunc)super_vectorcall,
};
More information about the Python-checkins
mailing list