From 27c074751823d313b1cec59a061f6520ce8cad0a Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 20 Sep 2020 14:23:05 +1000 Subject: [PATCH 1/3] Allow tuples with one item to give single color value in getink --- Tests/test_image.py | 6 ++++++ Tests/test_image_access.py | 21 ++++++--------------- src/_imaging.c | 5 ++++- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Tests/test_image.py b/Tests/test_image.py index 89894c9a773..ef0f1477f74 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -498,6 +498,12 @@ def test_storage_neg(self): with pytest.raises(ValueError): Image.core.fill("RGB", (2, -2), (0, 0, 0)) + def test_one_item_tuple(self): + for mode in ("I", "F", "L"): + im = Image.new(mode, (100, 100), (5,)) + px = im.load() + assert px[0, 0] == 5 + def test_linear_gradient_wrong_mode(self): # Arrange wrong_mode = "RGB" diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index 9afeb77f7ae..5ec3120463d 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -328,26 +328,17 @@ def test_p_putpixel_rgb_rgba(self): class TestImagePutPixelError(AccessTest): - IMAGE_MODES1 = ["L", "LA", "RGB", "RGBA"] - IMAGE_MODES2 = ["I", "I;16", "BGR;15"] - INVALID_TYPES1 = ["foo", 1.0, None] - INVALID_TYPES2 = [*INVALID_TYPES1, (10,)] + IMAGE_MODES = ["L", "LA", "RGB", "RGBA", "I", "I;16", "BGR;15"] + INVALID_TYPES = ["foo", 1.0, None] - @pytest.mark.parametrize("mode", IMAGE_MODES1) - def test_putpixel_type_error1(self, mode): + @pytest.mark.parametrize("mode", IMAGE_MODES) + def test_putpixel_type_error(self, mode): im = hopper(mode) - for v in self.INVALID_TYPES1: + for v in self.INVALID_TYPES: with pytest.raises(TypeError, match="color must be int or tuple"): im.putpixel((0, 0), v) - @pytest.mark.parametrize("mode", IMAGE_MODES2) - def test_putpixel_type_error2(self, mode): - im = hopper(mode) - for v in self.INVALID_TYPES2: - with pytest.raises(TypeError, match="color must be int"): - im.putpixel((0, 0), v) - - @pytest.mark.parametrize("mode", IMAGE_MODES1 + IMAGE_MODES2) + @pytest.mark.parametrize("mode", IMAGE_MODES) def test_putpixel_overflow_error(self, mode): im = hopper(mode) with pytest.raises(OverflowError): diff --git a/src/_imaging.c b/src/_imaging.c index d3159a49415..58975900ad7 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -518,6 +518,9 @@ getink(PyObject* color, Imaging im, char* ink) be cast to either UINT8 or INT32 */ int rIsInt = 0; + if (PyTuple_Check(color) && PyTuple_Size(color) == 1) { + color = PyTuple_GetItem(color, 0); + } if (im->type == IMAGING_TYPE_UINT8 || im->type == IMAGING_TYPE_INT32 || im->type == IMAGING_TYPE_SPECIAL) { @@ -533,7 +536,7 @@ getink(PyObject* color, Imaging im, char* ink) return NULL; } } else { - PyErr_SetString(PyExc_TypeError, "color must be int"); + PyErr_SetString(PyExc_TypeError, "color must be int or tuple"); return NULL; } } From e01081bf8b85f3b24d2fbe0ea2c00c62cdd7015d Mon Sep 17 00:00:00 2001 From: Andrew Murray <3112309+radarhere@users.noreply.github.com> Date: Tue, 22 Sep 2020 08:36:29 +1000 Subject: [PATCH 2/3] Improved error message Co-authored-by: nulano --- src/_imaging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_imaging.c b/src/_imaging.c index 58975900ad7..fad13ae8a4e 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -536,7 +536,7 @@ getink(PyObject* color, Imaging im, char* ink) return NULL; } } else { - PyErr_SetString(PyExc_TypeError, "color must be int or tuple"); + PyErr_SetString(PyExc_TypeError, "color must be int or single-element tuple"); return NULL; } } From b304a13bca506f04b18b1cc44074d3ce14896dad Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 22 Sep 2020 13:06:52 +1000 Subject: [PATCH 3/3] Updated test --- Tests/test_image_access.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index 5ec3120463d..e86dc8530f0 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -328,17 +328,27 @@ def test_p_putpixel_rgb_rgba(self): class TestImagePutPixelError(AccessTest): - IMAGE_MODES = ["L", "LA", "RGB", "RGBA", "I", "I;16", "BGR;15"] + IMAGE_MODES1 = ["L", "LA", "RGB", "RGBA"] + IMAGE_MODES2 = ["I", "I;16", "BGR;15"] INVALID_TYPES = ["foo", 1.0, None] - @pytest.mark.parametrize("mode", IMAGE_MODES) - def test_putpixel_type_error(self, mode): + @pytest.mark.parametrize("mode", IMAGE_MODES1) + def test_putpixel_type_error1(self, mode): im = hopper(mode) for v in self.INVALID_TYPES: with pytest.raises(TypeError, match="color must be int or tuple"): im.putpixel((0, 0), v) - @pytest.mark.parametrize("mode", IMAGE_MODES) + @pytest.mark.parametrize("mode", IMAGE_MODES2) + def test_putpixel_type_error2(self, mode): + im = hopper(mode) + for v in self.INVALID_TYPES: + with pytest.raises( + TypeError, match="color must be int or single-element tuple" + ): + im.putpixel((0, 0), v) + + @pytest.mark.parametrize("mode", IMAGE_MODES1 + IMAGE_MODES2) def test_putpixel_overflow_error(self, mode): im = hopper(mode) with pytest.raises(OverflowError):