Repository: python-pillow/Pillow

Problem statement:
"Unknown resampling filter" error message can be improved
https://github.com/python-pillow/Pillow/blob/2766d943a1a39ea5beafd3cc10b115f5b608a9ab/src/PIL/Image.py#L1797

https://github.com/python-pillow/Pillow/blob/2766d943a1a39ea5beafd3cc10b115f5b608a9ab/src/PIL/Image.py#L2266

1. "unknown" feels vague/wrong. The resampling filter may very well be a valid one that Pillow is aware of _in general_, it's just that it's _unsupported_ for the current use-case.
2. The error could include both the sampling filter passed in _and_ what filters are supported/expected. Both of these are currently hard to gleam without reading the source code.


Hints:
1. `resize` supports all the available filters, so in that case, the supplied filter is unknown.
2. When you say that it is hard to determine which filters are supported without reading the source code, https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transform and https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.resize list the relevant filters.

Patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -1794,7 +1794,18 @@ def resize(self, size, resample=NEAREST, box=None):
         if resample not in (
                 NEAREST, BILINEAR, BICUBIC, LANCZOS, BOX, HAMMING,
         ):
-            raise ValueError("unknown resampling filter")
+            message = "Unknown resampling filter ({}).".format(resample)
+
+            filters = ["{} ({})".format(filter[1], filter[0]) for filter in (
+                (NEAREST, "Image.NEAREST"),
+                (LANCZOS, "Image.LANCZOS"),
+                (BILINEAR, "Image.BILINEAR"),
+                (BICUBIC, "Image.BICUBIC"),
+                (BOX, "Image.BOX"),
+                (HAMMING, "Image.HAMMING")
+            )]
+            raise ValueError(
+                message+" Use "+", ".join(filters[:-1])+" or "+filters[-1])
 
         size = tuple(size)
 
@@ -2263,7 +2274,22 @@ def __transformer(self, box, image, method, data,
             raise ValueError("unknown transformation method")
 
         if resample not in (NEAREST, BILINEAR, BICUBIC):
-            raise ValueError("unknown resampling filter")
+            if resample in (BOX, HAMMING, LANCZOS):
+                message = {
+                    BOX: "Image.BOX",
+                    HAMMING: "Image.HAMMING",
+                    LANCZOS: "Image.LANCZOS/Image.ANTIALIAS"
+                }[resample]+" ({}) cannot be used.".format(resample)
+            else:
+                message = "Unknown resampling filter ({}).".format(resample)
+
+            filters = ["{} ({})".format(filter[1], filter[0]) for filter in (
+                (NEAREST, "Image.NEAREST"),
+                (BILINEAR, "Image.BILINEAR"),
+                (BICUBIC, "Image.BICUBIC")
+            )]
+            raise ValueError(
+                message+" Use "+", ".join(filters[:-1])+" or "+filters[-1])
 
         image.load()
 


Test patch:
diff --git a/Tests/test_image_transform.py b/Tests/test_image_transform.py
--- a/Tests/test_image_transform.py
+++ b/Tests/test_image_transform.py
@@ -160,6 +160,15 @@ def test_missing_method_data(self):
         im = hopper()
         self.assertRaises(ValueError, im.transform, (100, 100), None)
 
+    def test_unknown_resampling_filter(self):
+        im = hopper()
+        (w, h) = im.size
+        for resample in (Image.BOX, "unknown"):
+            self.assertRaises(ValueError, im.transform, (100, 100), Image.EXTENT,
+                              (0, 0,
+                               w, h),
+                              resample)
+
 
 class TestImageTransformAffine(PillowTestCase):
     transform = Image.AFFINE