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):
|
||||
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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue