mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-28 18:10:33 +03:00
Merge pull request #6184 from hugovk/deprecations-helper
Add deprecations helper
This commit is contained in:
commit
535c45717f
91
Tests/test_deprecate.py
Normal file
91
Tests/test_deprecate.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from PIL import _deprecate
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"version, expected",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
10,
|
||||||
|
"Old thing is deprecated and will be removed in Pillow 10 "
|
||||||
|
r"\(2023-07-01\)\. Use new thing instead\.",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
None,
|
||||||
|
r"Old thing is deprecated and will be removed in a future version\. "
|
||||||
|
r"Use new thing instead\.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_version(version, expected):
|
||||||
|
with pytest.warns(DeprecationWarning, match=expected):
|
||||||
|
_deprecate.deprecate("Old thing", version, "new thing")
|
||||||
|
|
||||||
|
|
||||||
|
def test_unknown_version():
|
||||||
|
expected = r"Unknown removal version, update PIL\._deprecate\?"
|
||||||
|
with pytest.raises(ValueError, match=expected):
|
||||||
|
_deprecate.deprecate("Old thing", 12345, "new thing")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"deprecated, plural, expected",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"Old thing",
|
||||||
|
False,
|
||||||
|
r"Old thing is deprecated and should be removed\.",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Old things",
|
||||||
|
True,
|
||||||
|
r"Old things are deprecated and should be removed\.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_old_version(deprecated, plural, expected):
|
||||||
|
expected = r""
|
||||||
|
with pytest.raises(RuntimeError, match=expected):
|
||||||
|
_deprecate.deprecate(deprecated, 1, plural=plural)
|
||||||
|
|
||||||
|
|
||||||
|
def test_plural():
|
||||||
|
expected = (
|
||||||
|
r"Old things are deprecated and will be removed in Pillow 10 \(2023-07-01\)\. "
|
||||||
|
r"Use new thing instead\."
|
||||||
|
)
|
||||||
|
with pytest.warns(DeprecationWarning, match=expected):
|
||||||
|
_deprecate.deprecate("Old things", 10, "new thing", plural=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_replacement_and_action():
|
||||||
|
expected = "Use only one of 'replacement' and 'action'"
|
||||||
|
with pytest.raises(ValueError, match=expected):
|
||||||
|
_deprecate.deprecate(
|
||||||
|
"Old thing", 10, replacement="new thing", action="Upgrade to new thing"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"action",
|
||||||
|
[
|
||||||
|
"Upgrade to new thing",
|
||||||
|
"Upgrade to new thing.",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_action(action):
|
||||||
|
expected = (
|
||||||
|
r"Old thing is deprecated and will be removed in Pillow 10 \(2023-07-01\)\. "
|
||||||
|
r"Upgrade to new thing\."
|
||||||
|
)
|
||||||
|
with pytest.warns(DeprecationWarning, match=expected):
|
||||||
|
_deprecate.deprecate("Old thing", 10, action=action)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_replacement_or_action():
|
||||||
|
expected = (
|
||||||
|
r"Old thing is deprecated and will be removed in Pillow 10 \(2023-07-01\)"
|
||||||
|
)
|
||||||
|
with pytest.warns(DeprecationWarning, match=expected):
|
||||||
|
_deprecate.deprecate("Old thing", 10)
|
|
@ -9,6 +9,14 @@ Internal Modules
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
:mod:`~PIL._deprecate` Module
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
.. automodule:: PIL._deprecate
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
:mod:`~PIL._tkinter_finder` Module
|
:mod:`~PIL._tkinter_finder` Module
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,11 @@ BLP files come in many different flavours:
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
import warnings
|
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
|
|
||||||
class Format(IntEnum):
|
class Format(IntEnum):
|
||||||
|
@ -55,7 +55,6 @@ class AlphaEncoding(IntEnum):
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
|
|
||||||
for enum, prefix in {
|
for enum, prefix in {
|
||||||
Format: "BLP_FORMAT_",
|
Format: "BLP_FORMAT_",
|
||||||
Encoding: "BLP_ENCODING_",
|
Encoding: "BLP_ENCODING_",
|
||||||
|
@ -64,19 +63,7 @@ def __getattr__(name):
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
name = name[len(prefix) :]
|
name = name[len(prefix) :]
|
||||||
if name in enum.__members__:
|
if name in enum.__members__:
|
||||||
warnings.warn(
|
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||||
prefix
|
|
||||||
+ name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use "
|
|
||||||
+ enum.__name__
|
|
||||||
+ "."
|
|
||||||
+ name
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return enum[name]
|
return enum[name]
|
||||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,8 @@
|
||||||
# See the README file for information on usage and redistribution.
|
# See the README file for information on usage and redistribution.
|
||||||
#
|
#
|
||||||
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from . import FitsImagePlugin, Image, ImageFile
|
from . import FitsImagePlugin, Image, ImageFile
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
_handler = None
|
_handler = None
|
||||||
|
|
||||||
|
@ -25,11 +24,11 @@ def register_handler(handler):
|
||||||
global _handler
|
global _handler
|
||||||
_handler = handler
|
_handler = handler
|
||||||
|
|
||||||
warnings.warn(
|
deprecate(
|
||||||
"FitsStubImagePlugin is deprecated and will be removed in Pillow "
|
"FitsStubImagePlugin",
|
||||||
"10 (2023-07-01). FITS images can now be read without a handler through "
|
10,
|
||||||
"FitsImagePlugin instead.",
|
action="FITS images can now be read without "
|
||||||
DeprecationWarning,
|
"a handler through FitsImagePlugin instead",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Override FitsImagePlugin with this handler
|
# Override FitsImagePlugin with this handler
|
||||||
|
|
|
@ -52,11 +52,11 @@ Note: All data is stored in little-Endian (Intel) byte order.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
import warnings
|
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
MAGIC = b"FTEX"
|
MAGIC = b"FTEX"
|
||||||
|
|
||||||
|
@ -67,24 +67,11 @@ class Format(IntEnum):
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
|
|
||||||
for enum, prefix in {Format: "FORMAT_"}.items():
|
for enum, prefix in {Format: "FORMAT_"}.items():
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
name = name[len(prefix) :]
|
name = name[len(prefix) :]
|
||||||
if name in enum.__members__:
|
if name in enum.__members__:
|
||||||
warnings.warn(
|
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||||
prefix
|
|
||||||
+ name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use "
|
|
||||||
+ enum.__name__
|
|
||||||
+ "."
|
|
||||||
+ name
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return enum[name]
|
return enum[name]
|
||||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||||
|
|
||||||
|
|
|
@ -50,28 +50,17 @@ except ImportError:
|
||||||
# Use __version__ instead.
|
# Use __version__ instead.
|
||||||
from . import ImageMode, TiffTags, UnidentifiedImageError, __version__, _plugins
|
from . import ImageMode, TiffTags, UnidentifiedImageError, __version__, _plugins
|
||||||
from ._binary import i32le, o32be, o32le
|
from ._binary import i32le, o32be, o32le
|
||||||
|
from ._deprecate import deprecate
|
||||||
from ._util import deferred_error, isPath
|
from ._util import deferred_error, isPath
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
|
|
||||||
categories = {"NORMAL": 0, "SEQUENCE": 1, "CONTAINER": 2}
|
categories = {"NORMAL": 0, "SEQUENCE": 1, "CONTAINER": 2}
|
||||||
if name in categories:
|
if name in categories:
|
||||||
warnings.warn(
|
deprecate("Image categories", 10, "is_animated", plural=True)
|
||||||
"Image categories are " + deprecated + "Use is_animated instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return categories[name]
|
return categories[name]
|
||||||
elif name in ("NEAREST", "NONE"):
|
elif name in ("NEAREST", "NONE"):
|
||||||
warnings.warn(
|
deprecate(name, 10, "Resampling.NEAREST or Dither.NONE")
|
||||||
name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use Resampling.NEAREST or Dither.NONE instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
old_resampling = {
|
old_resampling = {
|
||||||
"LINEAR": "BILINEAR",
|
"LINEAR": "BILINEAR",
|
||||||
|
@ -79,31 +68,11 @@ def __getattr__(name):
|
||||||
"ANTIALIAS": "LANCZOS",
|
"ANTIALIAS": "LANCZOS",
|
||||||
}
|
}
|
||||||
if name in old_resampling:
|
if name in old_resampling:
|
||||||
warnings.warn(
|
deprecate(name, 10, f"Resampling.{old_resampling[name]}")
|
||||||
name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use Resampling."
|
|
||||||
+ old_resampling[name]
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return Resampling[old_resampling[name]]
|
return Resampling[old_resampling[name]]
|
||||||
for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize):
|
for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize):
|
||||||
if name in enum.__members__:
|
if name in enum.__members__:
|
||||||
warnings.warn(
|
deprecate(name, 10, f"{enum.__name__}.{name}")
|
||||||
name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use "
|
|
||||||
+ enum.__name__
|
|
||||||
+ "."
|
|
||||||
+ name
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return enum[name]
|
return enum[name]
|
||||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||||
|
|
||||||
|
@ -538,12 +507,7 @@ class Image:
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if name == "category":
|
if name == "category":
|
||||||
warnings.warn(
|
deprecate("Image categories", 10, "is_animated", plural=True)
|
||||||
"Image categories are deprecated and will be removed in Pillow 10 "
|
|
||||||
"(2023-07-01). Use is_animated instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return self._category
|
return self._category
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
# below for the original description.
|
# below for the original description.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PIL import _imagingcms
|
from PIL import _imagingcms
|
||||||
except ImportError as ex:
|
except ImportError as ex:
|
||||||
|
@ -117,24 +118,11 @@ class Direction(IntEnum):
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
|
|
||||||
for enum, prefix in {Intent: "INTENT_", Direction: "DIRECTION_"}.items():
|
for enum, prefix in {Intent: "INTENT_", Direction: "DIRECTION_"}.items():
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
name = name[len(prefix) :]
|
name = name[len(prefix) :]
|
||||||
if name in enum.__members__:
|
if name in enum.__members__:
|
||||||
warnings.warn(
|
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||||
prefix
|
|
||||||
+ name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use "
|
|
||||||
+ enum.__name__
|
|
||||||
+ "."
|
|
||||||
+ name
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return enum[name]
|
return enum[name]
|
||||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
|
from ._deprecate import deprecate
|
||||||
from ._util import isDirectory, isPath
|
from ._util import isDirectory, isPath
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,24 +43,11 @@ class Layout(IntEnum):
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
|
|
||||||
for enum, prefix in {Layout: "LAYOUT_"}.items():
|
for enum, prefix in {Layout: "LAYOUT_"}.items():
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
name = name[len(prefix) :]
|
name = name[len(prefix) :]
|
||||||
if name in enum.__members__:
|
if name in enum.__members__:
|
||||||
warnings.warn(
|
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||||
prefix
|
|
||||||
+ name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use "
|
|
||||||
+ enum.__name__
|
|
||||||
+ "."
|
|
||||||
+ name
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return enum[name]
|
return enum[name]
|
||||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||||
|
|
||||||
|
@ -196,8 +184,6 @@ class FreeTypeFont:
|
||||||
if core.HAVE_RAQM:
|
if core.HAVE_RAQM:
|
||||||
layout_engine = Layout.RAQM
|
layout_engine = Layout.RAQM
|
||||||
elif layout_engine == Layout.RAQM and not core.HAVE_RAQM:
|
elif layout_engine == Layout.RAQM and not core.HAVE_RAQM:
|
||||||
import warnings
|
|
||||||
|
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"Raqm layout was requested, but Raqm is not available. "
|
"Raqm layout was requested, but Raqm is not available. "
|
||||||
"Falling back to basic layout."
|
"Falling back to basic layout."
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import array
|
import array
|
||||||
import warnings
|
|
||||||
|
|
||||||
from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile
|
from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
|
|
||||||
class ImagePalette:
|
class ImagePalette:
|
||||||
|
@ -40,11 +40,7 @@ class ImagePalette:
|
||||||
self.palette = palette or bytearray()
|
self.palette = palette or bytearray()
|
||||||
self.dirty = None
|
self.dirty = None
|
||||||
if size != 0:
|
if size != 0:
|
||||||
warnings.warn(
|
deprecate("The size parameter", 10, None)
|
||||||
"The size parameter is deprecated and will be removed in Pillow 10 "
|
|
||||||
"(2023-07-01).",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
if size != len(self.palette):
|
if size != len(self.palette):
|
||||||
raise ValueError("wrong palette size")
|
raise ValueError("wrong palette size")
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,12 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from shlex import quote
|
from shlex import quote
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
_viewers = []
|
_viewers = []
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,11 +121,7 @@ class Viewer:
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
@ -176,11 +173,7 @@ class MacViewer(Viewer):
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
@ -228,11 +221,7 @@ class XDGViewer(UnixViewer):
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
@ -261,11 +250,7 @@ class DisplayViewer(UnixViewer):
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
@ -296,11 +281,7 @@ class GmDisplayViewer(UnixViewer):
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
@ -325,11 +306,7 @@ class EogViewer(UnixViewer):
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
@ -360,11 +337,7 @@ class XVViewer(UnixViewer):
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
if "file" in options:
|
if "file" in options:
|
||||||
warnings.warn(
|
deprecate("The 'file' argument", 10, "'path'")
|
||||||
"The 'file' argument is deprecated and will be removed in Pillow "
|
|
||||||
"10 (2023-07-01). Use 'path' instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
path = options.pop("file")
|
path = options.pop("file")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Missing required argument: 'path'")
|
raise TypeError("Missing required argument: 'path'")
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import tkinter
|
import tkinter
|
||||||
import warnings
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Check for Tkinter interface hooks
|
# Check for Tkinter interface hooks
|
||||||
|
@ -187,11 +187,7 @@ class PhotoImage:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if box is not None:
|
if box is not None:
|
||||||
warnings.warn(
|
deprecate("The box parameter", 10, None)
|
||||||
"The box parameter is deprecated and will be removed in Pillow 10 "
|
|
||||||
"(2023-07-01).",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
|
|
||||||
# convert to blittable
|
# convert to blittable
|
||||||
im.load()
|
im.load()
|
||||||
|
|
|
@ -45,6 +45,7 @@ from . import Image, ImageFile, TiffImagePlugin
|
||||||
from ._binary import i16be as i16
|
from ._binary import i16be as i16
|
||||||
from ._binary import i32be as i32
|
from ._binary import i32be as i32
|
||||||
from ._binary import o8
|
from ._binary import o8
|
||||||
|
from ._deprecate import deprecate
|
||||||
from .JpegPresets import presets
|
from .JpegPresets import presets
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -603,11 +604,7 @@ samplings = {
|
||||||
|
|
||||||
|
|
||||||
def convert_dict_qtables(qtables):
|
def convert_dict_qtables(qtables):
|
||||||
warnings.warn(
|
deprecate("convert_dict_qtables", 10, action="Conversion is no longer needed")
|
||||||
"convert_dict_qtables is deprecated and will be removed in Pillow 10"
|
|
||||||
"(2023-07-01). Conversion is no longer needed.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
|
||||||
return qtables
|
return qtables
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ from ._binary import i32be as i32
|
||||||
from ._binary import o8
|
from ._binary import o8
|
||||||
from ._binary import o16be as o16
|
from ._binary import o16be as o16
|
||||||
from ._binary import o32be as o32
|
from ._binary import o32be as o32
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -131,24 +132,11 @@ class Blend(IntEnum):
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
|
|
||||||
for enum, prefix in {Disposal: "APNG_DISPOSE_", Blend: "APNG_BLEND_"}.items():
|
for enum, prefix in {Disposal: "APNG_DISPOSE_", Blend: "APNG_BLEND_"}.items():
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
name = name[len(prefix) :]
|
name = name[len(prefix) :]
|
||||||
if name in enum.__members__:
|
if name in enum.__members__:
|
||||||
warnings.warn(
|
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||||
prefix
|
|
||||||
+ name
|
|
||||||
+ " is "
|
|
||||||
+ deprecated
|
|
||||||
+ "Use "
|
|
||||||
+ enum.__name__
|
|
||||||
+ "."
|
|
||||||
+ name
|
|
||||||
+ " instead.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return enum[name]
|
return enum[name]
|
||||||
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
||||||
|
|
||||||
|
|
66
src/PIL/_deprecate.py
Normal file
66
src/PIL/_deprecate.py
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
from . import __version__
|
||||||
|
|
||||||
|
|
||||||
|
def deprecate(
|
||||||
|
deprecated: str,
|
||||||
|
when: int | None,
|
||||||
|
replacement: str | None = None,
|
||||||
|
*,
|
||||||
|
action: str | None = None,
|
||||||
|
plural: bool = False,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Deprecations helper.
|
||||||
|
|
||||||
|
:param deprecated: Name of thing to be deprecated.
|
||||||
|
:param when: Pillow major version to be removed in.
|
||||||
|
:param replacement: Name of replacement.
|
||||||
|
:param action: Instead of "replacement", give a custom call to action
|
||||||
|
e.g. "Upgrade to new thing".
|
||||||
|
:param plural: if the deprecated thing is plural, needing "are" instead of "is".
|
||||||
|
|
||||||
|
Usually of the form:
|
||||||
|
|
||||||
|
"[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd).
|
||||||
|
Use [replacement] instead."
|
||||||
|
|
||||||
|
You can leave out the replacement sentence:
|
||||||
|
|
||||||
|
"[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd)"
|
||||||
|
|
||||||
|
Or with another call to action:
|
||||||
|
|
||||||
|
"[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd).
|
||||||
|
[action]."
|
||||||
|
"""
|
||||||
|
|
||||||
|
is_ = "are" if plural else "is"
|
||||||
|
|
||||||
|
if when is None:
|
||||||
|
removed = "a future version"
|
||||||
|
elif when <= int(__version__.split(".")[0]):
|
||||||
|
raise RuntimeError(f"{deprecated} {is_} deprecated and should be removed.")
|
||||||
|
elif when == 10:
|
||||||
|
removed = "Pillow 10 (2023-07-01)"
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unknown removal version, update {__name__}?")
|
||||||
|
|
||||||
|
if replacement and action:
|
||||||
|
raise ValueError("Use only one of 'replacement' and 'action'")
|
||||||
|
|
||||||
|
if replacement:
|
||||||
|
action = f". Use {replacement} instead."
|
||||||
|
elif action:
|
||||||
|
action = f". {action.rstrip('.')}."
|
||||||
|
else:
|
||||||
|
action = ""
|
||||||
|
|
||||||
|
warnings.warn(
|
||||||
|
f"{deprecated} {is_} deprecated and will be removed in {removed}{action}",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=3,
|
||||||
|
)
|
|
@ -2,9 +2,10 @@
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import tkinter
|
import tkinter
|
||||||
import warnings
|
|
||||||
from tkinter import _tkinter as tk
|
from tkinter import _tkinter as tk
|
||||||
|
|
||||||
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hasattr(sys, "pypy_find_executable"):
|
if hasattr(sys, "pypy_find_executable"):
|
||||||
TKINTER_LIB = tk.tklib_cffi.__file__
|
TKINTER_LIB = tk.tklib_cffi.__file__
|
||||||
|
@ -17,9 +18,6 @@ except AttributeError:
|
||||||
|
|
||||||
tk_version = str(tkinter.TkVersion)
|
tk_version = str(tkinter.TkVersion)
|
||||||
if tk_version == "8.4":
|
if tk_version == "8.4":
|
||||||
warnings.warn(
|
deprecate(
|
||||||
"Support for Tk/Tcl 8.4 is deprecated and will be removed"
|
"Support for Tk/Tcl 8.4", 10, action="Please upgrade to Tk/Tcl 8.5 or newer"
|
||||||
" in Pillow 10 (2023-07-01). Please upgrade to Tk/Tcl 8.5 "
|
|
||||||
"or newer.",
|
|
||||||
DeprecationWarning,
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user