diff options
author | Victor Stinner <vstinner@python.org> | 2024-05-10 19:08:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-10 19:08:24 (GMT) |
commit | aa36f83c1670f1e41fa9432a20e5c4a88ee9012c (patch) | |
tree | 2dfa668791a82aa1e7725c75e74ed1baa09ae8fa /Objects/exceptions.c | |
parent | ec9d12be9648ee60a2eb02d67069d74f8b314df9 (diff) | |
download | cpython-aa36f83c1670f1e41fa9432a20e5c4a88ee9012c.zip cpython-aa36f83c1670f1e41fa9432a20e5c4a88ee9012c.tar.gz cpython-aa36f83c1670f1e41fa9432a20e5c4a88ee9012c.tar.bz2 |
gh-118702: Implement vectorcall for BaseException (#118703)
* BaseException_vectorcall() now creates a tuple from 'args' array.
* Creation an exception using BaseException_vectorcall() is now a
single function call, rather than having to call
BaseException_new() and then BaseException_init().
Calling BaseException_init() is inefficient since it overrides
the 'args' attribute.
* _PyErr_SetKeyError() now uses PyObject_CallOneArg() to create the
KeyError instance to use BaseException_vectorcall().
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r-- | Objects/exceptions.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 63c461d..f9cd577 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -78,6 +78,40 @@ BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) return 0; } + +static PyObject * +BaseException_vectorcall(PyObject *type_obj, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + PyTypeObject *type = _PyType_CAST(type_obj); + if (!_PyArg_NoKwnames(type->tp_name, kwnames)) { + return NULL; + } + + PyBaseExceptionObject *self; + self = (PyBaseExceptionObject *)type->tp_alloc(type, 0); + if (!self) { + return NULL; + } + + // The dict is created on the fly in PyObject_GenericSetAttr() + self->dict = NULL; + self->notes = NULL; + self->traceback = NULL; + self->cause = NULL; + self->context = NULL; + self->suppress_context = 0; + + self->args = _PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf)); + if (!self->args) { + Py_DECREF(self); + return NULL; + } + + return (PyObject *)self; +} + + static int BaseException_clear(PyBaseExceptionObject *self) { @@ -486,6 +520,7 @@ static PyTypeObject _PyExc_BaseException = { (initproc)BaseException_init, /* tp_init */ 0, /* tp_alloc */ BaseException_new, /* tp_new */ + .tp_vectorcall = BaseException_vectorcall, }; /* the CPython API expects exceptions to be (PyObject *) - both a hold-over from the previous implementation and also allowing Python objects to be used @@ -3675,6 +3710,11 @@ _PyExc_InitTypes(PyInterpreterState *interp) if (_PyStaticType_InitBuiltin(interp, exc) < 0) { return -1; } + if (exc->tp_new == BaseException_new + && exc->tp_init == (initproc)BaseException_init) + { + exc->tp_vectorcall = BaseException_vectorcall; + } } return 0; } |