Implement Python vectorcall calling convention for Color type in colors.c
Fixes #9674
This commit is contained in:
parent
780b4337e4
commit
d97850274f
1 changed files with 41 additions and 1 deletions
|
|
@ -682,6 +682,45 @@ new_color(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) {
|
|||
return (PyObject*) alloc_color(r, g, b, a);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
color_vectorcall(PyObject *type UNUSED, PyObject *const *args, size_t nargsf, PyObject *kwnames) {
|
||||
const Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
|
||||
if (nargs > 4) {
|
||||
PyErr_SetString(PyExc_TypeError, "Color() takes at most 4 arguments");
|
||||
return NULL;
|
||||
}
|
||||
unsigned char rgba[4] = {0, 0, 0, 0};
|
||||
for (Py_ssize_t i = 0; i < nargs; i++) {
|
||||
unsigned long val = PyLong_AsUnsignedLongMask(args[i]);
|
||||
if (val == (unsigned long)-1 && PyErr_Occurred()) return NULL;
|
||||
rgba[i] = (unsigned char)val;
|
||||
}
|
||||
if (kwnames) {
|
||||
static const char *const kwnames_list[] = {"red", "green", "blue", "alpha"};
|
||||
const Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames);
|
||||
for (Py_ssize_t i = 0; i < nkwargs; i++) {
|
||||
const char *name = PyUnicode_AsUTF8(PyTuple_GET_ITEM(kwnames, i));
|
||||
if (!name) return NULL;
|
||||
int idx = -1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (strcmp(name, kwnames_list[j]) == 0) { idx = j; break; }
|
||||
}
|
||||
if (idx < 0) {
|
||||
PyErr_Format(PyExc_TypeError, "Color() got an unexpected keyword argument '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
if (idx < nargs) {
|
||||
PyErr_Format(PyExc_TypeError, "Color() got multiple values for argument '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
unsigned long val = PyLong_AsUnsignedLongMask(args[nargs + i]);
|
||||
if (val == (unsigned long)-1 && PyErr_Occurred()) return NULL;
|
||||
rgba[idx] = (unsigned char)val;
|
||||
}
|
||||
}
|
||||
return (PyObject*)alloc_color(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
Color_as_int(Color *self) {
|
||||
return PyLong_FromUnsignedLong(self->color.val);
|
||||
|
|
@ -1140,9 +1179,10 @@ PyTypeObject Color_Type = {
|
|||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "kitty.fast_data_types.Color",
|
||||
.tp_basicsize = sizeof(Color),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_VECTORCALL,
|
||||
.tp_doc = "Color",
|
||||
.tp_new = new_color,
|
||||
.tp_vectorcall = color_vectorcall,
|
||||
.tp_getset = color_getsetters,
|
||||
.tp_as_number = &color_number_methods,
|
||||
.tp_methods = color_methods,
|
||||
|
|
|
|||
Loading…
Reference in a new issue