mirror of https://github.com/python/cpython
bpo-46921: Vectorcall support for `super()` (GH-31687)
Co-Authored-By: Dong-hee Na <donghee.na@python.org>
This commit is contained in:
parent
2d8b764210
commit
602024e6e1
|
@ -317,6 +317,14 @@ class TestSuper(unittest.TestCase):
|
||||||
for i in range(1000):
|
for i in range(1000):
|
||||||
super.__init__(sp, int, i)
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Support vectorcall for ``super()``. Patch by Ken Jin.
|
|
@ -9000,19 +9000,28 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
super_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
superobject *su = (superobject *)self;
|
|
||||||
PyTypeObject *type = NULL;
|
PyTypeObject *type = NULL;
|
||||||
PyObject *obj = NULL;
|
PyObject *obj = NULL;
|
||||||
PyTypeObject *obj_type = NULL;
|
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("super", kwds))
|
if (!_PyArg_NoKeywords("super", kwds))
|
||||||
return -1;
|
return -1;
|
||||||
if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj))
|
if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj))
|
||||||
return -1;
|
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) {
|
if (type == NULL) {
|
||||||
/* Call super(), without args -- fill in from __class__
|
/* Call super(), without args -- fill in from __class__
|
||||||
and first local variable on the stack. */
|
and first local variable on the stack. */
|
||||||
|
@ -9072,6 +9081,47 @@ super_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
return 0;
|
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 = {
|
PyTypeObject PySuper_Type = {
|
||||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
"super", /* tp_name */
|
"super", /* tp_name */
|
||||||
|
@ -9114,4 +9164,5 @@ PyTypeObject PySuper_Type = {
|
||||||
PyType_GenericAlloc, /* tp_alloc */
|
PyType_GenericAlloc, /* tp_alloc */
|
||||||
PyType_GenericNew, /* tp_new */
|
PyType_GenericNew, /* tp_new */
|
||||||
PyObject_GC_Del, /* tp_free */
|
PyObject_GC_Del, /* tp_free */
|
||||||
|
.tp_vectorcall = (vectorcallfunc)super_vectorcall,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue