[FIX] core, web: Pillow 9.1 deprecations

Pillow 9.1 deprecates most if not all toplevel Image constants:
https://pillow.readthedocs.io/en/stable/releasenotes/9.1.0.html#constants

These constants have been moved to thematic enum classes (e.g. all the
resampling constants in `PIL.Image.Resampling`).

This triggers warnings in Odoo, and the removal delay is quite short
(slated for Pillow 10, release planned mid 2023). Pillow 9.1 is also
already in Debian Bookworm (current testing).

Fix by shimming at the import level: if the enums are available import
them into the local namespace, otherwise alias `PIL.Image` itself as
to the enum.

closes odoo/odoo#96799

X-original-commit: 7be04d31bad078681ef0a2919234c11840a2e8e2
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2022-07-28 02:40:23 +02:00
parent 7140779a68
commit e75f2989b4
2 changed files with 21 additions and 14 deletions
+5 -2
View File
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import markupsafe
from PIL import Image
from markupsafe import Markup
from odoo import api, fields, models, tools
@@ -14,6 +13,10 @@ except ImportError:
# If the `sass` python library isn't found, we fallback on the
# `sassc` executable in the path.
libsass = None
try:
from PIL.Image import Resampling
except ImportError:
from PIL import Image as Resampling
DEFAULT_PRIMARY = '#000000'
DEFAULT_SECONDARY = '#000000'
@@ -204,7 +207,7 @@ class BaseDocumentLayout(models.TransientModel):
# Converts to RGBA (if already RGBA, this is a noop)
image_converted = image.convert('RGBA')
image_resized = image_converted.resize((w, h), resample=Image.NEAREST)
image_resized = image_converted.resize((w, h), resample=Resampling.NEAREST)
colors = []
for color in image_resized.getcolors(w * h):
+16 -12
View File
@@ -7,6 +7,10 @@ import io
from PIL import Image, ImageOps
# We can preload Ico too because it is considered safe
from PIL import IcoImagePlugin
try:
from PIL.Image import Transpose, Palette, Resampling
except ImportError:
Transpose = Palette = Resampling = Image
from random import randrange
@@ -30,16 +34,16 @@ FILETYPE_BASE64_MAGICWORD = {
EXIF_TAG_ORIENTATION = 0x112
# The target is to have 1st row/col to be top/left
# Note: rotate is counterclockwise
EXIF_TAG_ORIENTATION_TO_TRANSPOSE_METHODS = { # Initial side on 1st row/col:
0: [], # reserved
1: [], # top/left
2: [Image.FLIP_LEFT_RIGHT], # top/right
3: [Image.ROTATE_180], # bottom/right
4: [Image.FLIP_TOP_BOTTOM], # bottom/left
5: [Image.FLIP_LEFT_RIGHT, Image.ROTATE_90], # left/top
6: [Image.ROTATE_270], # right/top
7: [Image.FLIP_TOP_BOTTOM, Image.ROTATE_90], # right/bottom
8: [Image.ROTATE_90], # left/bottom
EXIF_TAG_ORIENTATION_TO_TRANSPOSE_METHODS = { # Initial side on 1st row/col:
0: [], # reserved
1: [], # top/left
2: [Transpose.FLIP_LEFT_RIGHT], # top/right
3: [Transpose.ROTATE_180], # bottom/right
4: [Transpose.FLIP_TOP_BOTTOM], # bottom/left
5: [Transpose.FLIP_LEFT_RIGHT, Transpose.ROTATE_90],# left/top
6: [Transpose.ROTATE_270], # right/top
7: [Transpose.FLIP_TOP_BOTTOM, Transpose.ROTATE_90],# right/bottom
8: [Transpose.ROTATE_90], # left/bottom
}
# Arbitrary limit to fit most resolutions, including Nokia Lumia 1020 photo,
@@ -134,7 +138,7 @@ class ImageProcess():
if quality:
if output_image.mode != 'P':
# Floyd Steinberg dithering by default
output_image = output_image.convert('RGBA').convert('P', palette=Image.WEB, colors=256)
output_image = output_image.convert('RGBA').convert('P', palette=Palette.WEB, colors=256)
if output_format == 'JPEG':
opt['optimize'] = True
opt['quality'] = quality or 95
@@ -171,7 +175,7 @@ class ImageProcess():
asked_width = max_width or (w * max_height) // h
asked_height = max_height or (h * max_width) // w
if asked_width != w or asked_height != h:
self.image.thumbnail((asked_width, asked_height), Image.LANCZOS)
self.image.thumbnail((asked_width, asked_height), Resampling.LANCZOS)
if self.image.width != w or self.image.height != h:
self.operationsCount += 1
return self