Skip to content

Commit 295a033

Browse files
authored
Merge pull request #3078 from pygame-community/ankith26-scale-by-arg
Fix `(F)Rect.scale_by(_ip)` handling of the `scale_by` parameter
2 parents 1a28571 + 0299629 commit 295a033

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

docs/reST/ref/rect.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@
175175

176176
.. versionadded:: 2.3.1
177177

178+
.. versionchanged:: 2.5.2 the argument ``scale_by`` can now be passed as a positional argument
179+
178180
.. ## Rect.scale_by ##
179181
180182
.. method:: scale_by_ip
@@ -187,6 +189,8 @@
187189

188190
.. versionadded:: 2.3.1
189191

192+
.. versionchanged:: 2.5.2 the argument ``scale_by`` can now be passed as a positional argument
193+
190194
.. ## Rect.scale_by_ip ##
191195
192196
.. method:: update

src_c/rect_impl.h

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,31 +1084,40 @@ static PyObject *
10841084
RectExport_scalebyIp(RectObject *self, PyObject *args, PyObject *kwargs)
10851085
{
10861086
float factor_x, factor_y = 0;
1087-
1088-
static char *keywords[] = {"x", "y", NULL};
1089-
1090-
if (kwargs) {
1091-
PyObject *scale_by = PyDict_GetItemString(kwargs, "scale_by");
1092-
float temp_x, temp_y = 0;
1093-
1094-
if (scale_by) {
1095-
if (PyDict_Size(kwargs) > 1) {
1096-
return RAISE(PyExc_TypeError,
1097-
"The 'scale_by' keyword cannot be combined with "
1098-
"other arguments.");
1087+
PyObject *scale_by =
1088+
kwargs ? PyDict_GetItemString(kwargs, "scale_by") : NULL;
1089+
if (scale_by) {
1090+
if (PyDict_Size(kwargs) > 1) {
1091+
return RAISE(PyExc_TypeError,
1092+
"The 'scale_by' keyword cannot be combined with "
1093+
"other arguments.");
1094+
}
1095+
if (!pg_TwoFloatsFromObj(scale_by, &factor_x, &factor_y)) {
1096+
return RAISE(PyExc_TypeError,
1097+
"The 'scale_by' argument must be a number pair");
1098+
}
1099+
}
1100+
else {
1101+
static char *keywords[] = {"x", "y", NULL};
1102+
PyObject *arg_x, *arg_y = NULL;
1103+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", keywords, &arg_x,
1104+
&arg_y)) {
1105+
return NULL;
1106+
}
1107+
if (!pg_TwoFloatsFromObj(arg_x, &factor_x, &factor_y)) {
1108+
/* Not a sequence, so try handling int separately */
1109+
if (!pg_FloatFromObj(arg_x, &factor_x)) {
1110+
return RAISE(PyExc_TypeError, "Argument 'x' must be a number");
10991111
}
1100-
if (!pg_TwoFloatsFromObj(scale_by, &temp_x, &temp_y)) {
1101-
return RAISE(PyExc_TypeError, "number pair expected");
1112+
if (arg_y && !pg_FloatFromObj(arg_y, &factor_y)) {
1113+
return RAISE(PyExc_TypeError, "Argument 'y' must be a number");
11021114
}
1103-
PyDict_SetItemString(kwargs, "x", PyFloat_FromDouble(temp_x));
1104-
PyDict_SetItemString(kwargs, "y", PyFloat_FromDouble(temp_y));
1105-
PyDict_DelItemString(kwargs, "scale_by");
11061115
}
1107-
}
1108-
1109-
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "f|f", keywords, &factor_x,
1110-
&factor_y)) {
1111-
return RAISE(PyExc_TypeError, "Float values expected.");
1116+
else if (arg_y) {
1117+
return RAISE(
1118+
PyExc_TypeError,
1119+
"Cannot pass argument 'y' after passing a sequence scale");
1120+
}
11121121
}
11131122

11141123
factor_x = factor_x < 0 ? -factor_x : factor_x;
@@ -1130,7 +1139,11 @@ RectExport_scaleby(RectObject *self, PyObject *args, PyObject *kwargs)
11301139
{
11311140
RectObject *returnRect = (RectObject *)RectExport_subtypeNew4(
11321141
Py_TYPE(self), self->r.x, self->r.y, self->r.w, self->r.h);
1133-
RectExport_scalebyIp(returnRect, args, kwargs);
1142+
PyObject *tmp = RectExport_scalebyIp(returnRect, args, kwargs);
1143+
if (!tmp) {
1144+
return NULL;
1145+
}
1146+
Py_DECREF(tmp);
11341147
return (PyObject *)returnRect;
11351148
}
11361149

test/rect_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,8 @@ def test_scale_by__larger_kwargs_scale_by(self):
893893
r = Rect(2, 4, 6, 8)
894894
# act
895895
r2 = r.scale_by(scale_by=(2, 4))
896+
r3 = r.scale_by((2, 4))
897+
self.assertEqual(r2, r3)
896898
# assert
897899
self.assertEqual(r.center, r2.center)
898900
self.assertEqual(r.left - 3, r2.left)
@@ -3091,6 +3093,8 @@ def test_scale_by__larger_kwargs_scale_by(self):
30913093
r = FRect(2.1, 4, 6, 8.9)
30923094
# act
30933095
r2 = r.scale_by(scale_by=(2, 4))
3096+
r3 = r.scale_by((2, 4))
3097+
self.assertEqual(r2, r3)
30943098
# assert
30953099
self.assertSeqAlmostEqual5(r.center, r2.center)
30963100
self.assertAlmostEqual5(r.left - 3, r2.left)

0 commit comments

Comments
 (0)