diff --git a/src_c/rect.c b/src_c/rect.c index 9ee0979c68..b300c2f97f 100644 --- a/src_c/rect.c +++ b/src_c/rect.c @@ -469,8 +469,7 @@ static struct PyMethodDef pg_rect_methods[] = { {"update", (PyCFunction)pg_rect_update, METH_FASTCALL, DOC_RECT_UPDATE}, {"inflate", (PyCFunction)pg_rect_inflate, METH_VARARGS, DOC_RECT_INFLATE}, {"union", (PyCFunction)pg_rect_union, METH_FASTCALL, DOC_RECT_UNION}, - {"unionall", (PyCFunction)pg_rect_unionall, METH_VARARGS, - DOC_RECT_UNIONALL}, + {"unionall", (PyCFunction)pg_rect_unionall, METH_O, DOC_RECT_UNIONALL}, {"move_ip", (PyCFunction)pg_rect_move_ip, METH_FASTCALL, DOC_RECT_MOVEIP}, {"move_to", (PyCFunction)pg_rect_move_to, METH_FASTCALL | METH_KEYWORDS, DOC_RECT_MOVETO}, @@ -482,7 +481,7 @@ static struct PyMethodDef pg_rect_methods[] = { METH_VARARGS | METH_KEYWORDS, DOC_RECT_SCALEBYIP}, {"union_ip", (PyCFunction)pg_rect_union_ip, METH_FASTCALL, DOC_RECT_UNIONIP}, - {"unionall_ip", (PyCFunction)pg_rect_unionall_ip, METH_VARARGS, + {"unionall_ip", (PyCFunction)pg_rect_unionall_ip, METH_O, DOC_RECT_UNIONALLIP}, {"collidepoint", (PyCFunction)pg_rect_collidepoint, METH_FASTCALL, DOC_RECT_COLLIDEPOINT}, @@ -521,8 +520,7 @@ static struct PyMethodDef pg_frect_methods[] = { {"update", (PyCFunction)pg_frect_update, METH_FASTCALL, DOC_RECT_UPDATE}, {"inflate", (PyCFunction)pg_frect_inflate, METH_VARARGS, DOC_RECT_INFLATE}, {"union", (PyCFunction)pg_frect_union, METH_FASTCALL, DOC_RECT_UNION}, - {"unionall", (PyCFunction)pg_frect_unionall, METH_VARARGS, - DOC_RECT_UNIONALL}, + {"unionall", (PyCFunction)pg_frect_unionall, METH_O, DOC_RECT_UNIONALL}, {"move_ip", (PyCFunction)pg_frect_move_ip, METH_FASTCALL, DOC_RECT_MOVEIP}, {"move_to", (PyCFunction)pg_frect_move_to, METH_FASTCALL | METH_KEYWORDS, DOC_RECT_MOVETO}, @@ -534,7 +532,7 @@ static struct PyMethodDef pg_frect_methods[] = { METH_VARARGS | METH_KEYWORDS, DOC_RECT_SCALEBYIP}, {"union_ip", (PyCFunction)pg_frect_union_ip, METH_FASTCALL, DOC_RECT_UNIONIP}, - {"unionall_ip", (PyCFunction)pg_frect_unionall_ip, METH_VARARGS, + {"unionall_ip", (PyCFunction)pg_frect_unionall_ip, METH_O, DOC_RECT_UNIONALLIP}, {"collidepoint", (PyCFunction)pg_frect_collidepoint, METH_FASTCALL, DOC_RECT_COLLIDEPOINT}, diff --git a/src_c/rect_impl.h b/src_c/rect_impl.h index e10947cac6..64c13c7f81 100644 --- a/src_c/rect_impl.h +++ b/src_c/rect_impl.h @@ -1164,17 +1164,14 @@ RectExport_unionIp(RectObject *self, PyObject *const *args, Py_ssize_t nargs) } static PyObject * -RectExport_unionall(RectObject *self, PyObject *args) +RectExport_unionall(RectObject *self, PyObject *arg) { InnerRect *argrect, temp; Py_ssize_t loop, size; - PyObject *list, *obj; + PyObject *obj; PrimitiveType t, l, b, r; - if (!PyArg_ParseTuple(args, "O", &list)) { - return NULL; - } - if (!PySequence_Check(list)) { + if (!PySequence_Check(arg)) { return RAISE(PyExc_TypeError, "Argument must be a sequence of rectstyle objects."); } @@ -1183,44 +1180,67 @@ RectExport_unionall(RectObject *self, PyObject *args) t = self->r.y; r = self->r.x + self->r.w; b = self->r.y + self->r.h; - size = PySequence_Length(list); /*warning, size could be -1 on error?*/ - if (size < 1) { - if (size < 0) { - /*Error.*/ - return NULL; + + if (pgSequenceFast_Check(arg)) { + PyObject **items = PySequence_Fast_ITEMS(arg); + size = PySequence_Fast_GET_SIZE(arg); + + if (size < 1) { + /*Empty arg: nothing to be done.*/ + return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t); + } + + for (loop = 0; loop < size; ++loop) { + if (!(argrect = RectFromObject(items[loop], &temp))) { + return RAISE( + PyExc_TypeError, + "Argument must be a sequence of rectstyle objects."); + } + l = MIN(l, argrect->x); + t = MIN(t, argrect->y); + r = MAX(r, argrect->x + argrect->w); + b = MAX(b, argrect->y + argrect->h); } - /*Empty list: nothing to be done.*/ - return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t); } + else { + size = PySequence_Length(arg); /*warning, size could be -1 on error?*/ + if (size < 1) { + if (size < 0) { + /*Error.*/ + return NULL; + } + /*Empty arg: nothing to be done.*/ + return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t); + } - for (loop = 0; loop < size; ++loop) { - obj = PySequence_GetItem(list, loop); - if (!obj || !(argrect = RectFromObject(obj, &temp))) { - Py_XDECREF(obj); - return RAISE(PyExc_TypeError, - "Argument must be a sequence of rectstyle objects."); + for (loop = 0; loop < size; ++loop) { + obj = PySequence_ITEM(arg, loop); + if (!obj || !(argrect = RectFromObject(obj, &temp))) { + Py_XDECREF(obj); + return RAISE( + PyExc_TypeError, + "Argument must be a sequence of rectstyle objects."); + } + l = MIN(l, argrect->x); + t = MIN(t, argrect->y); + r = MAX(r, argrect->x + argrect->w); + b = MAX(b, argrect->y + argrect->h); + Py_DECREF(obj); } - l = MIN(l, argrect->x); - t = MIN(t, argrect->y); - r = MAX(r, argrect->x + argrect->w); - b = MAX(b, argrect->y + argrect->h); - Py_DECREF(obj); } + return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t); } static PyObject * -RectExport_unionallIp(RectObject *self, PyObject *args) +RectExport_unionallIp(RectObject *self, PyObject *arg) { InnerRect *argrect, temp; Py_ssize_t loop, size; - PyObject *list, *obj; + PyObject *obj; PrimitiveType t, l, b, r; - if (!PyArg_ParseTuple(args, "O", &list)) { - return NULL; - } - if (!PySequence_Check(list)) { + if (!PySequence_Check(arg)) { return RAISE(PyExc_TypeError, "Argument must be a sequence of rectstyle objects."); } @@ -1230,34 +1250,59 @@ RectExport_unionallIp(RectObject *self, PyObject *args) r = self->r.x + self->r.w; b = self->r.y + self->r.h; - size = PySequence_Length(list); /*warning, size could be -1 on error?*/ - if (size < 1) { - if (size < 0) { - /*Error.*/ - return NULL; + if (pgSequenceFast_Check(arg)) { + PyObject **items = PySequence_Fast_ITEMS(arg); + size = PySequence_Fast_GET_SIZE(arg); + + if (size < 1) { + /*Empty arg: nothing to be done.*/ + Py_RETURN_NONE; + } + + for (loop = 0; loop < size; ++loop) { + if (!(argrect = RectFromObject(items[loop], &temp))) { + return RAISE( + PyExc_TypeError, + "Argument must be a sequence of rectstyle objects."); + } + l = MIN(l, argrect->x); + t = MIN(t, argrect->y); + r = MAX(r, argrect->x + argrect->w); + b = MAX(b, argrect->y + argrect->h); } - /*Empty list: nothing to be done.*/ - Py_RETURN_NONE; } + else { + size = PySequence_Length(arg); /*warning, size could be -1 on error?*/ + if (size < 1) { + if (size < 0) { + /*Error.*/ + return NULL; + } + /*Empty arg: nothing to be done.*/ + Py_RETURN_NONE; + } - for (loop = 0; loop < size; ++loop) { - obj = PySequence_GetItem(list, loop); - if (!obj || !(argrect = RectFromObject(obj, &temp))) { - Py_XDECREF(obj); - return RAISE(PyExc_TypeError, - "Argument must be a sequence of rectstyle objects."); + for (loop = 0; loop < size; ++loop) { + obj = PySequence_ITEM(arg, loop); + if (!obj || !(argrect = RectFromObject(obj, &temp))) { + Py_XDECREF(obj); + return RAISE( + PyExc_TypeError, + "Argument must be a sequence of rectstyle objects."); + } + l = MIN(l, argrect->x); + t = MIN(t, argrect->y); + r = MAX(r, argrect->x + argrect->w); + b = MAX(b, argrect->y + argrect->h); + Py_DECREF(obj); } - l = MIN(l, argrect->x); - t = MIN(t, argrect->y); - r = MAX(r, argrect->x + argrect->w); - b = MAX(b, argrect->y + argrect->h); - Py_DECREF(obj); } self->r.x = l; self->r.y = t; self->r.w = r - l; self->r.h = b - t; + Py_RETURN_NONE; }