mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 17:06:16 +03:00
Merge branch 'main' into include-dir-type-confusion
This commit is contained in:
commit
6fce7d6ed4
|
@ -43,7 +43,7 @@ if [[ $(uname) != CYGWIN* ]]; then
|
|||
# PyQt6 doesn't support PyPy3
|
||||
if [[ $GHA_PYTHON_VERSION == 3.* ]]; then
|
||||
sudo apt-get -qq install libegl1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxkbcommon-x11-0
|
||||
python3 -m pip install pyqt6
|
||||
python3 -m pip install pyqt6 PyQt6-Qt6!=6.5.0
|
||||
fi
|
||||
|
||||
# webp
|
||||
|
|
1
.github/workflows/test-cygwin.yml
vendored
1
.github/workflows/test-cygwin.yml
vendored
|
@ -67,7 +67,6 @@ jobs:
|
|||
python3${{ matrix.python-minor-version }}-numpy
|
||||
python3${{ matrix.python-minor-version }}-sip
|
||||
python3${{ matrix.python-minor-version }}-tkinter
|
||||
qt5-devel-tools
|
||||
wget
|
||||
xorg-server-extra
|
||||
zlib-devel
|
||||
|
|
|
@ -5,6 +5,9 @@ Changelog (Pillow)
|
|||
10.0.0 (unreleased)
|
||||
-------------------
|
||||
|
||||
- Remove deprecations for Pillow 10.0.0 #7059
|
||||
[hugovk, radarhere]
|
||||
|
||||
- Drop support for soon-EOL Python 3.7 #7058
|
||||
[hugovk, radarhere]
|
||||
|
||||
|
|
1
Makefile
1
Makefile
|
@ -78,6 +78,7 @@ debug:
|
|||
|
||||
.PHONY: release-test
|
||||
release-test:
|
||||
python3 Tests/check_release_notes.py
|
||||
python3 -m pip install -e .[tests]
|
||||
python3 selftest.py
|
||||
python3 -m pytest Tests
|
||||
|
|
6
Tests/check_release_notes.py
Normal file
6
Tests/check_release_notes.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
for rst in Path("docs/releasenotes").glob("[1-9]*.rst"):
|
||||
if "TODO" in open(rst).read():
|
||||
sys.exit(f"Error: remove TODO from {rst}")
|
|
@ -1,18 +0,0 @@
|
|||
import warnings
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
# Arrange: cause all warnings to always be triggered
|
||||
warnings.simplefilter("always")
|
||||
|
||||
# Act: trigger a warning with Qt5
|
||||
from PIL import ImageQt
|
||||
|
||||
|
||||
def test_deprecated():
|
||||
# Assert
|
||||
if ImageQt.qt_version in ("5", "side2"):
|
||||
assert len(w) == 1
|
||||
assert issubclass(w[0].category, DeprecationWarning)
|
||||
assert "deprecated" in str(w[0].message)
|
||||
else:
|
||||
assert len(w) == 0
|
|
@ -655,13 +655,3 @@ def test_different_modes_in_later_frames(mode, tmp_path):
|
|||
im.save(test_file, save_all=True, append_images=[Image.new(mode, (1, 1))])
|
||||
with Image.open(test_file) as reloaded:
|
||||
assert reloaded.mode == mode
|
||||
|
||||
|
||||
def test_constants_deprecation():
|
||||
for enum, prefix in {
|
||||
PngImagePlugin.Disposal: "APNG_DISPOSE_",
|
||||
PngImagePlugin.Blend: "APNG_BLEND_",
|
||||
}.items():
|
||||
for name in enum.__members__:
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert getattr(PngImagePlugin, prefix + name) == enum[name]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from PIL import BlpImagePlugin, Image
|
||||
from PIL import Image
|
||||
|
||||
from .helper import (
|
||||
assert_image_equal,
|
||||
|
@ -72,14 +72,3 @@ def test_crashes(test_file):
|
|||
with Image.open(f) as im:
|
||||
with pytest.raises(OSError):
|
||||
im.load()
|
||||
|
||||
|
||||
def test_constants_deprecation():
|
||||
for enum, prefix in {
|
||||
BlpImagePlugin.Format: "BLP_FORMAT_",
|
||||
BlpImagePlugin.Encoding: "BLP_ENCODING_",
|
||||
BlpImagePlugin.AlphaEncoding: "BLP_ALPHA_ENCODING_",
|
||||
}.items():
|
||||
for name in enum.__members__:
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert getattr(BlpImagePlugin, prefix + name) == enum[name]
|
||||
|
|
|
@ -2,7 +2,7 @@ from io import BytesIO
|
|||
|
||||
import pytest
|
||||
|
||||
from PIL import FitsImagePlugin, FitsStubImagePlugin, Image
|
||||
from PIL import FitsImagePlugin, Image
|
||||
|
||||
from .helper import assert_image_equal, hopper
|
||||
|
||||
|
@ -48,39 +48,3 @@ def test_comment():
|
|||
image_data = b"SIMPLE = T / comment string"
|
||||
with pytest.raises(OSError):
|
||||
FitsImagePlugin.FitsImageFile(BytesIO(image_data))
|
||||
|
||||
|
||||
def test_stub_deprecated():
|
||||
class Handler:
|
||||
opened = False
|
||||
loaded = False
|
||||
|
||||
def open(self, im):
|
||||
self.opened = True
|
||||
|
||||
def load(self, im):
|
||||
self.loaded = True
|
||||
im.fp.close()
|
||||
return Image.new("RGB", (1, 1))
|
||||
|
||||
handler = Handler()
|
||||
with pytest.warns(DeprecationWarning):
|
||||
FitsStubImagePlugin.register_handler(handler)
|
||||
|
||||
with Image.open(TEST_FILE) as im:
|
||||
assert im.format == "FITS"
|
||||
assert im.size == (128, 128)
|
||||
assert im.mode == "L"
|
||||
|
||||
assert handler.opened
|
||||
assert not handler.loaded
|
||||
|
||||
im.load()
|
||||
assert handler.loaded
|
||||
|
||||
FitsStubImagePlugin._handler = None
|
||||
Image.register_open(
|
||||
FitsImagePlugin.FitsImageFile.format,
|
||||
FitsImagePlugin.FitsImageFile,
|
||||
FitsImagePlugin._accept,
|
||||
)
|
||||
|
|
|
@ -21,12 +21,3 @@ def test_invalid_file():
|
|||
|
||||
with pytest.raises(SyntaxError):
|
||||
FtexImagePlugin.FtexImageFile(invalid_file)
|
||||
|
||||
|
||||
def test_constants_deprecation():
|
||||
for enum, prefix in {
|
||||
FtexImagePlugin.Format: "FORMAT_",
|
||||
}.items():
|
||||
for name in enum.__members__:
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert getattr(FtexImagePlugin, prefix + name) == enum[name]
|
||||
|
|
|
@ -636,12 +636,6 @@ class TestFileJpeg:
|
|||
assert max(im2.quantization[0]) <= 255
|
||||
assert max(im2.quantization[1]) <= 255
|
||||
|
||||
def test_convert_dict_qtables_deprecation(self):
|
||||
with pytest.warns(DeprecationWarning):
|
||||
qtable = {0: [1, 2, 3, 4]}
|
||||
qtable2 = JpegImagePlugin.convert_dict_qtables(qtable)
|
||||
assert qtable == qtable2
|
||||
|
||||
@pytest.mark.skipif(not djpeg_available(), reason="djpeg not available")
|
||||
def test_load_djpeg(self):
|
||||
with Image.open(TEST_FILE) as img:
|
||||
|
|
|
@ -929,25 +929,7 @@ class TestImage:
|
|||
im.apply_transparency()
|
||||
assert im.palette.colors[(27, 35, 6, 214)] == 24
|
||||
|
||||
def test_categories_deprecation(self):
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert hopper().category == 0
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.NORMAL == 0
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.SEQUENCE == 1
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.CONTAINER == 2
|
||||
|
||||
def test_constants(self):
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.LINEAR == Image.Resampling.BILINEAR
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.CUBIC == Image.Resampling.BICUBIC
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.ANTIALIAS == Image.Resampling.LANCZOS
|
||||
|
||||
for enum in (
|
||||
Image.Transpose,
|
||||
Image.Transform,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from .helper import assert_image_equal, hopper
|
||||
|
||||
|
||||
|
@ -62,8 +60,3 @@ def test_f_mode():
|
|||
im = hopper("F")
|
||||
with pytest.raises(ValueError):
|
||||
im.point(None)
|
||||
|
||||
|
||||
def test_coerce_e_deprecation():
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert Image.coerce_e(2).data == 2
|
||||
|
|
|
@ -617,16 +617,6 @@ def test_auxiliary_channels_isolated():
|
|||
assert_image_equal(test_image.convert(dst_format[2]), reference_image)
|
||||
|
||||
|
||||
def test_constants_deprecation():
|
||||
for enum, prefix in {
|
||||
ImageCms.Intent: "INTENT_",
|
||||
ImageCms.Direction: "DIRECTION_",
|
||||
}.items():
|
||||
for name in enum.__members__:
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert getattr(ImageCms, prefix + name) == enum[name]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ("RGB", "RGBA", "RGBX"))
|
||||
def test_rgb_lab(mode):
|
||||
im = Image.new(mode, (1, 1))
|
||||
|
|
|
@ -1083,14 +1083,6 @@ def test_woff2(layout_engine):
|
|||
assert_image_similar_tofile(im, "Tests/images/test_woff2.png", 5)
|
||||
|
||||
|
||||
def test_fill_deprecation(font):
|
||||
with pytest.warns(DeprecationWarning):
|
||||
font.getmask2("Hello world", fill=Image.core.fill)
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.raises(TypeError):
|
||||
font.getmask2("Hello world", fill=None)
|
||||
|
||||
|
||||
def test_render_mono_size():
|
||||
# issue 4177
|
||||
|
||||
|
@ -1130,12 +1122,3 @@ def test_raqm_missing_warning(monkeypatch):
|
|||
"Raqm layout was requested, but Raqm is not available. "
|
||||
"Falling back to basic layout."
|
||||
)
|
||||
|
||||
|
||||
def test_constants_deprecation():
|
||||
for enum, prefix in {
|
||||
ImageFont.Layout: "LAYOUT_",
|
||||
}.items():
|
||||
for name in enum.__members__:
|
||||
with pytest.warns(DeprecationWarning):
|
||||
assert getattr(ImageFont, prefix + name) == enum[name]
|
||||
|
|
|
@ -9,10 +9,6 @@ def test_sanity():
|
|||
palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3)
|
||||
assert len(palette.colors) == 256
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
with pytest.raises(ValueError):
|
||||
ImagePalette.ImagePalette("RGB", list(range(256)) * 3, 10)
|
||||
|
||||
|
||||
def test_reload():
|
||||
with Image.open("Tests/images/hopper.gif") as im:
|
||||
|
|
|
@ -2,13 +2,10 @@ import warnings
|
|||
|
||||
import pytest
|
||||
|
||||
from PIL import ImageQt
|
||||
|
||||
from .helper import assert_image_similar, hopper
|
||||
|
||||
with warnings.catch_warnings() as w:
|
||||
warnings.simplefilter("ignore", category=DeprecationWarning)
|
||||
from PIL import ImageQt
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not ImageQt.qt_is_installed, reason="Qt bindings are not installed"
|
||||
)
|
||||
|
@ -26,10 +23,6 @@ def test_rgb():
|
|||
from PyQt6.QtGui import qRgb
|
||||
elif ImageQt.qt_version == "side6":
|
||||
from PySide6.QtGui import qRgb
|
||||
elif ImageQt.qt_version == "5":
|
||||
from PyQt5.QtGui import qRgb
|
||||
elif ImageQt.qt_version == "side2":
|
||||
from PySide2.QtGui import qRgb
|
||||
|
||||
assert qRgb(0, 0, 0) == qRgba(0, 0, 0, 255)
|
||||
|
||||
|
|
|
@ -89,20 +89,3 @@ def test_ipythonviewer():
|
|||
|
||||
im = hopper()
|
||||
assert test_viewer.show(im) == 1
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not on_ci() or is_win32(),
|
||||
reason="Only run on CIs; hangs on Windows CIs",
|
||||
)
|
||||
@pytest.mark.parametrize("viewer", ImageShow._viewers)
|
||||
def test_file_deprecated(tmp_path, viewer):
|
||||
f = str(tmp_path / "temp.jpg")
|
||||
hopper().save(f)
|
||||
with pytest.warns(DeprecationWarning):
|
||||
try:
|
||||
viewer.show_file(file=f)
|
||||
except NotImplementedError:
|
||||
pass
|
||||
with pytest.raises(TypeError):
|
||||
viewer.show_file()
|
||||
|
|
|
@ -89,13 +89,6 @@ def test_photoimage_blank(mode):
|
|||
assert_image_equal(reloaded.convert(mode), im)
|
||||
|
||||
|
||||
def test_box_deprecation():
|
||||
im = hopper()
|
||||
im_tk = ImageTk.PhotoImage(im)
|
||||
with pytest.warns(DeprecationWarning):
|
||||
im_tk.paste(im, (0, 0, 128, 128))
|
||||
|
||||
|
||||
def test_bitmapimage():
|
||||
im = hopper("1")
|
||||
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", category=DeprecationWarning)
|
||||
from PIL import ImageQt
|
||||
from PIL import ImageQt
|
||||
|
||||
from .helper import assert_image_equal_tofile, assert_image_similar, hopper
|
||||
|
||||
|
@ -19,14 +15,6 @@ if ImageQt.qt_is_installed:
|
|||
from PySide6.QtCore import QPoint
|
||||
from PySide6.QtGui import QImage, QPainter, QRegion
|
||||
from PySide6.QtWidgets import QApplication, QHBoxLayout, QLabel, QWidget
|
||||
elif ImageQt.qt_version == "5":
|
||||
from PyQt5.QtCore import QPoint
|
||||
from PyQt5.QtGui import QImage, QPainter, QRegion
|
||||
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QLabel, QWidget
|
||||
elif ImageQt.qt_version == "side2":
|
||||
from PySide2.QtCore import QPoint
|
||||
from PySide2.QtGui import QImage, QPainter, QRegion
|
||||
from PySide2.QtWidgets import QApplication, QHBoxLayout, QLabel, QWidget
|
||||
|
||||
class Example(QWidget):
|
||||
def __init__(self):
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", category=DeprecationWarning)
|
||||
from PIL import ImageQt
|
||||
from PIL import ImageQt
|
||||
|
||||
from .helper import assert_image_equal, assert_image_equal_tofile, hopper
|
||||
|
||||
|
@ -32,7 +28,7 @@ def test_sanity(mode, tmp_path):
|
|||
assert_image_equal(rt, src)
|
||||
|
||||
if mode == "1":
|
||||
# BW appears to not save correctly on QT5
|
||||
# BW appears to not save correctly on Qt
|
||||
# kicks out errors on console:
|
||||
# libpng warning: Invalid color type/bit depth combination
|
||||
# in IHDR
|
||||
|
|
|
@ -12,150 +12,6 @@ Deprecated features
|
|||
Below are features which are considered deprecated. Where appropriate,
|
||||
a ``DeprecationWarning`` is issued.
|
||||
|
||||
Tk/Tcl 8.4
|
||||
~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.2.0
|
||||
|
||||
Support for Tk/Tcl 8.4 is deprecated and will be removed in Pillow 10.0.0 (2023-07-01),
|
||||
when Tk/Tcl 8.5 will be the minimum supported.
|
||||
|
||||
Categories
|
||||
~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.2.0
|
||||
|
||||
``im.category`` is deprecated and will be removed in Pillow 10.0.0 (2023-07-01),
|
||||
along with the related ``Image.NORMAL``, ``Image.SEQUENCE`` and
|
||||
``Image.CONTAINER`` attributes.
|
||||
|
||||
To determine if an image has multiple frames or not,
|
||||
``getattr(im, "is_animated", False)`` can be used instead.
|
||||
|
||||
JpegImagePlugin.convert_dict_qtables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.3.0
|
||||
|
||||
JPEG ``quantization`` is now automatically converted, but still returned as a
|
||||
dictionary. The :py:attr:`~PIL.JpegImagePlugin.convert_dict_qtables` method no longer
|
||||
performs any operations on the data given to it, has been deprecated and will be
|
||||
removed in Pillow 10.0.0 (2023-07-01).
|
||||
|
||||
ImagePalette size parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.4.0
|
||||
|
||||
The ``size`` parameter will be removed in Pillow 10.0.0 (2023-07-01).
|
||||
|
||||
Before Pillow 8.3.0, ``ImagePalette`` required palette data of particular lengths by
|
||||
default, and the size parameter could be used to override that. Pillow 8.3.0 removed
|
||||
the default required length, also removing the need for the size parameter.
|
||||
|
||||
ImageShow.Viewer.show_file file argument
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.1.0
|
||||
|
||||
The ``file`` argument in :py:meth:`~PIL.ImageShow.Viewer.show_file()` has been
|
||||
deprecated and will be removed in Pillow 10.0.0 (2023-07-01). It has been replaced by
|
||||
``path``.
|
||||
|
||||
In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.
|
||||
``viewer.show_file(file="test.jpg")`` will raise a deprecation warning, and suggest
|
||||
``viewer.show_file(path="test.jpg")`` instead.
|
||||
|
||||
Constants
|
||||
~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.1.0
|
||||
|
||||
A number of constants have been deprecated and will be removed in Pillow 10.0.0
|
||||
(2023-07-01). Instead, ``enum.IntEnum`` classes have been added.
|
||||
|
||||
.. note::
|
||||
|
||||
Additional ``Image`` constants were deprecated in Pillow 9.1.0, but that
|
||||
was reversed in Pillow 9.4.0 and those constants will now remain available.
|
||||
See :ref:`restored-image-constants`
|
||||
|
||||
===================================================== ============================================================
|
||||
Deprecated Use instead
|
||||
===================================================== ============================================================
|
||||
``Image.LINEAR`` ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
|
||||
``Image.CUBIC`` ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
|
||||
``Image.ANTIALIAS`` ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
|
||||
``ImageCms.INTENT_PERCEPTUAL`` ``ImageCms.Intent.PERCEPTUAL``
|
||||
``ImageCms.INTENT_RELATIVE_COLORMETRIC`` ``ImageCms.Intent.RELATIVE_COLORMETRIC``
|
||||
``ImageCms.INTENT_SATURATION`` ``ImageCms.Intent.SATURATION``
|
||||
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC`` ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
|
||||
``ImageCms.DIRECTION_INPUT`` ``ImageCms.Direction.INPUT``
|
||||
``ImageCms.DIRECTION_OUTPUT`` ``ImageCms.Direction.OUTPUT``
|
||||
``ImageCms.DIRECTION_PROOF`` ``ImageCms.Direction.PROOF``
|
||||
``ImageFont.LAYOUT_BASIC`` ``ImageFont.Layout.BASIC``
|
||||
``ImageFont.LAYOUT_RAQM`` ``ImageFont.Layout.RAQM``
|
||||
``BlpImagePlugin.BLP_FORMAT_JPEG`` ``BlpImagePlugin.Format.JPEG``
|
||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED`` ``BlpImagePlugin.Encoding.UNCOMPRESSED``
|
||||
``BlpImagePlugin.BLP_ENCODING_DXT`` ``BlpImagePlugin.Encoding.DXT``
|
||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA`` ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1`` ``BlpImagePlugin.AlphaEncoding.DXT1``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3`` ``BlpImagePlugin.AlphaEncoding.DXT3``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5`` ``BlpImagePlugin.AlphaEncoding.DXT5``
|
||||
``FtexImagePlugin.FORMAT_DXT1`` ``FtexImagePlugin.Format.DXT1``
|
||||
``FtexImagePlugin.FORMAT_UNCOMPRESSED`` ``FtexImagePlugin.Format.UNCOMPRESSED``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_NONE`` ``PngImagePlugin.Disposal.OP_NONE``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND`` ``PngImagePlugin.Disposal.OP_BACKGROUND``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS`` ``PngImagePlugin.Disposal.OP_PREVIOUS``
|
||||
``PngImagePlugin.APNG_BLEND_OP_SOURCE`` ``PngImagePlugin.Blend.OP_SOURCE``
|
||||
``PngImagePlugin.APNG_BLEND_OP_OVER`` ``PngImagePlugin.Blend.OP_OVER``
|
||||
===================================================== ============================================================
|
||||
|
||||
FitsStubImagePlugin
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.1.0
|
||||
|
||||
The stub image plugin ``FitsStubImagePlugin`` has been deprecated and will be removed in
|
||||
Pillow 10.0.0 (2023-07-01). FITS images can be read without a handler through
|
||||
:mod:`~PIL.FitsImagePlugin` instead.
|
||||
|
||||
FreeTypeFont.getmask2 fill parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
|
||||
The undocumented ``fill`` parameter of :py:meth:`.FreeTypeFont.getmask2` has been
|
||||
deprecated and will be removed in Pillow 10 (2023-07-01).
|
||||
|
||||
PhotoImage.paste box parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
|
||||
The ``box`` parameter is unused. It will be removed in Pillow 10.0.0 (2023-07-01).
|
||||
|
||||
PyQt5 and PySide2
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
|
||||
`Qt 5 reached end-of-life <https://www.qt.io/blog/qt-5.15-released>`_ on 2020-12-08 for
|
||||
open-source users (and will reach EOL on 2023-12-08 for commercial licence holders).
|
||||
|
||||
Support for PyQt5 and PySide2 has been deprecated from ``ImageQt`` and will be removed
|
||||
in Pillow 10 (2023-07-01). Upgrade to
|
||||
`PyQt6 <https://www.riverbankcomputing.com/static/Docs/PyQt6/>`_ or
|
||||
`PySide6 <https://doc.qt.io/qtforpython/>`_ instead.
|
||||
|
||||
Image.coerce_e
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
|
||||
This undocumented method has been deprecated and will be removed in Pillow 10
|
||||
(2023-07-01).
|
||||
|
||||
.. _Font size and offset methods:
|
||||
|
||||
Font size and offset methods
|
||||
|
@ -223,6 +79,149 @@ Removed features
|
|||
Deprecated features are only removed in major releases after an appropriate
|
||||
period of deprecation has passed.
|
||||
|
||||
Tk/Tcl 8.4
|
||||
~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.2.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
Support for Tk/Tcl 8.4 was removed in Pillow 10.0.0 (2023-07-01).
|
||||
|
||||
Categories
|
||||
~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.2.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
``im.category`` was removed along with the related ``Image.NORMAL``,
|
||||
``Image.SEQUENCE`` and ``Image.CONTAINER`` attributes.
|
||||
|
||||
To determine if an image has multiple frames or not,
|
||||
``getattr(im, "is_animated", False)`` can be used instead.
|
||||
|
||||
JpegImagePlugin.convert_dict_qtables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.3.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
Since deprecation in Pillow 8.3.0, the ``convert_dict_qtables`` method no longer
|
||||
performed any operations on the data given to it, and has been removed.
|
||||
|
||||
ImagePalette size parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 8.4.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
Before Pillow 8.3.0, ``ImagePalette`` required palette data of particular lengths by
|
||||
default, and the ``size`` parameter could be used to override that. Pillow 8.3.0
|
||||
removed the default required length, also removing the need for the ``size`` parameter.
|
||||
|
||||
ImageShow.Viewer.show_file file argument
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.1.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
The ``file`` argument in :py:meth:`~PIL.ImageShow.Viewer.show_file()` has been
|
||||
removed and replaced by ``path``.
|
||||
|
||||
In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.
|
||||
|
||||
Constants
|
||||
~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.1.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
A number of constants have been removed.
|
||||
Instead, ``enum.IntEnum`` classes have been added.
|
||||
|
||||
.. note::
|
||||
|
||||
Additional ``Image`` constants were deprecated in Pillow 9.1.0, but that
|
||||
was reversed in Pillow 9.4.0 and those constants will now remain available.
|
||||
See :ref:`restored-image-constants`
|
||||
|
||||
===================================================== ============================================================
|
||||
Removed Use instead
|
||||
===================================================== ============================================================
|
||||
``Image.LINEAR`` ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
|
||||
``Image.CUBIC`` ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
|
||||
``Image.ANTIALIAS`` ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
|
||||
``ImageCms.INTENT_PERCEPTUAL`` ``ImageCms.Intent.PERCEPTUAL``
|
||||
``ImageCms.INTENT_RELATIVE_COLORMETRIC`` ``ImageCms.Intent.RELATIVE_COLORMETRIC``
|
||||
``ImageCms.INTENT_SATURATION`` ``ImageCms.Intent.SATURATION``
|
||||
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC`` ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
|
||||
``ImageCms.DIRECTION_INPUT`` ``ImageCms.Direction.INPUT``
|
||||
``ImageCms.DIRECTION_OUTPUT`` ``ImageCms.Direction.OUTPUT``
|
||||
``ImageCms.DIRECTION_PROOF`` ``ImageCms.Direction.PROOF``
|
||||
``ImageFont.LAYOUT_BASIC`` ``ImageFont.Layout.BASIC``
|
||||
``ImageFont.LAYOUT_RAQM`` ``ImageFont.Layout.RAQM``
|
||||
``BlpImagePlugin.BLP_FORMAT_JPEG`` ``BlpImagePlugin.Format.JPEG``
|
||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED`` ``BlpImagePlugin.Encoding.UNCOMPRESSED``
|
||||
``BlpImagePlugin.BLP_ENCODING_DXT`` ``BlpImagePlugin.Encoding.DXT``
|
||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA`` ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1`` ``BlpImagePlugin.AlphaEncoding.DXT1``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3`` ``BlpImagePlugin.AlphaEncoding.DXT3``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5`` ``BlpImagePlugin.AlphaEncoding.DXT5``
|
||||
``FtexImagePlugin.FORMAT_DXT1`` ``FtexImagePlugin.Format.DXT1``
|
||||
``FtexImagePlugin.FORMAT_UNCOMPRESSED`` ``FtexImagePlugin.Format.UNCOMPRESSED``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_NONE`` ``PngImagePlugin.Disposal.OP_NONE``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND`` ``PngImagePlugin.Disposal.OP_BACKGROUND``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS`` ``PngImagePlugin.Disposal.OP_PREVIOUS``
|
||||
``PngImagePlugin.APNG_BLEND_OP_SOURCE`` ``PngImagePlugin.Blend.OP_SOURCE``
|
||||
``PngImagePlugin.APNG_BLEND_OP_OVER`` ``PngImagePlugin.Blend.OP_OVER``
|
||||
===================================================== ============================================================
|
||||
|
||||
FitsStubImagePlugin
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.1.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
The stub image plugin ``FitsStubImagePlugin`` has been removed.
|
||||
FITS images can be read without a handler through :mod:`~PIL.FitsImagePlugin` instead.
|
||||
|
||||
FreeTypeFont.getmask2 fill parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
The undocumented ``fill`` parameter of :py:meth:`.FreeTypeFont.getmask2` has been
|
||||
removed.
|
||||
|
||||
PhotoImage.paste box parameter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
The ``box`` parameter was unused and has been removed.
|
||||
|
||||
PyQt5 and PySide2
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
`Qt 5 reached end-of-life <https://www.qt.io/blog/qt-5.15-released>`_ on 2020-12-08 for
|
||||
open-source users (and will reach EOL on 2023-12-08 for commercial licence holders).
|
||||
|
||||
Support for PyQt5 and PySide2 has been removed from ``ImageQt``. Upgrade to
|
||||
`PyQt6 <https://www.riverbankcomputing.com/static/Docs/PyQt6/>`_ or
|
||||
`PySide6 <https://doc.qt.io/qtforpython/>`_ instead.
|
||||
|
||||
Image.coerce_e
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 9.2.0
|
||||
.. versionremoved:: 10.0.0
|
||||
|
||||
This undocumented method has been removed.
|
||||
|
||||
PILLOW_VERSION constant
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -412,18 +412,6 @@ See :ref:`concept-filters` for details.
|
|||
:undoc-members:
|
||||
:noindex:
|
||||
|
||||
Some deprecated filters are also available under the following names:
|
||||
|
||||
.. data:: NONE
|
||||
:noindex:
|
||||
:value: Resampling.NEAREST
|
||||
.. data:: LINEAR
|
||||
:value: Resampling.BILINEAR
|
||||
.. data:: CUBIC
|
||||
:value: Resampling.BICUBIC
|
||||
.. data:: ANTIALIAS
|
||||
:value: Resampling.LANCZOS
|
||||
|
||||
Dither modes
|
||||
^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -4,16 +4,8 @@
|
|||
:py:mod:`~PIL.ImageQt` Module
|
||||
=============================
|
||||
|
||||
The :py:mod:`~PIL.ImageQt` module contains support for creating PyQt6, PySide6, PyQt5
|
||||
or PySide2 QImage objects from PIL images.
|
||||
|
||||
`Qt 5 reached end-of-life <https://www.qt.io/blog/qt-5.15-released>`_ on 2020-12-08 for
|
||||
open-source users (and will reach EOL on 2023-12-08 for commercial licence holders).
|
||||
|
||||
Support for PyQt5 and PySide2 has been deprecated from ``ImageQt`` and will be removed
|
||||
in Pillow 10 (2023-07-01). Upgrade to
|
||||
`PyQt6 <https://www.riverbankcomputing.com/static/Docs/PyQt6/>`_ or
|
||||
`PySide6 <https://doc.qt.io/qtforpython/>`_ instead.
|
||||
The :py:mod:`~PIL.ImageQt` module contains support for creating PyQt6 or PySide6
|
||||
QImage objects from PIL images.
|
||||
|
||||
.. versionadded:: 1.1.6
|
||||
|
||||
|
@ -22,7 +14,7 @@ in Pillow 10 (2023-07-01). Upgrade to
|
|||
Creates an :py:class:`~PIL.ImageQt.ImageQt` object from a PIL
|
||||
:py:class:`~PIL.Image.Image` object. This class is a subclass of
|
||||
QtGui.QImage, which means that you can pass the resulting objects directly
|
||||
to PyQt6/PySide6/PyQt5/PySide2 API functions and methods.
|
||||
to PyQt6/PySide6 API functions and methods.
|
||||
|
||||
This operation is currently supported for mode 1, L, P, RGB, and RGBA
|
||||
images. To handle other modes, you need to convert the image first.
|
||||
|
|
149
docs/releasenotes/10.0.0.rst
Normal file
149
docs/releasenotes/10.0.0.rst
Normal file
|
@ -0,0 +1,149 @@
|
|||
10.0.0
|
||||
------
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
||||
Categories
|
||||
^^^^^^^^^^
|
||||
|
||||
``im.category`` has been removed, along with the related ``Image.NORMAL``,
|
||||
``Image.SEQUENCE`` and ``Image.CONTAINER`` attributes.
|
||||
|
||||
To determine if an image has multiple frames or not,
|
||||
``getattr(im, "is_animated", False)`` can be used instead.
|
||||
|
||||
Tk/Tcl 8.4
|
||||
^^^^^^^^^^
|
||||
|
||||
Support for Tk/Tcl 8.4 has been removed.
|
||||
|
||||
JpegImagePlugin.convert_dict_qtables
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Since deprecation in Pillow 8.3.0, the ``convert_dict_qtables`` method no longer
|
||||
performed any operations on the data given to it, and has been removed.
|
||||
|
||||
ImagePalette size parameter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before Pillow 8.3.0, ``ImagePalette`` required palette data of particular lengths by
|
||||
default, and the ``size`` parameter could be used to override that. Pillow 8.3.0
|
||||
removed the default required length, also removing the need for the ``size`` parameter.
|
||||
|
||||
ImageShow.Viewer.show_file file argument
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``file`` argument in :py:meth:`~PIL.ImageShow.Viewer.show_file()` has been
|
||||
removed and replaced by ``path``.
|
||||
|
||||
In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.
|
||||
|
||||
Constants
|
||||
^^^^^^^^^
|
||||
|
||||
A number of constants have been removed.
|
||||
Instead, ``enum.IntEnum`` classes have been added.
|
||||
|
||||
===================================================== ============================================================
|
||||
Removed Use instead
|
||||
===================================================== ============================================================
|
||||
``Image.LINEAR`` ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
|
||||
``Image.CUBIC`` ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
|
||||
``Image.ANTIALIAS`` ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
|
||||
``ImageCms.INTENT_PERCEPTUAL`` ``ImageCms.Intent.PERCEPTUAL``
|
||||
``ImageCms.INTENT_RELATIVE_COLORMETRIC`` ``ImageCms.Intent.RELATIVE_COLORMETRIC``
|
||||
``ImageCms.INTENT_SATURATION`` ``ImageCms.Intent.SATURATION``
|
||||
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC`` ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
|
||||
``ImageCms.DIRECTION_INPUT`` ``ImageCms.Direction.INPUT``
|
||||
``ImageCms.DIRECTION_OUTPUT`` ``ImageCms.Direction.OUTPUT``
|
||||
``ImageCms.DIRECTION_PROOF`` ``ImageCms.Direction.PROOF``
|
||||
``ImageFont.LAYOUT_BASIC`` ``ImageFont.Layout.BASIC``
|
||||
``ImageFont.LAYOUT_RAQM`` ``ImageFont.Layout.RAQM``
|
||||
``BlpImagePlugin.BLP_FORMAT_JPEG`` ``BlpImagePlugin.Format.JPEG``
|
||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED`` ``BlpImagePlugin.Encoding.UNCOMPRESSED``
|
||||
``BlpImagePlugin.BLP_ENCODING_DXT`` ``BlpImagePlugin.Encoding.DXT``
|
||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA`` ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1`` ``BlpImagePlugin.AlphaEncoding.DXT1``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3`` ``BlpImagePlugin.AlphaEncoding.DXT3``
|
||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5`` ``BlpImagePlugin.AlphaEncoding.DXT5``
|
||||
``FtexImagePlugin.FORMAT_DXT1`` ``FtexImagePlugin.Format.DXT1``
|
||||
``FtexImagePlugin.FORMAT_UNCOMPRESSED`` ``FtexImagePlugin.Format.UNCOMPRESSED``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_NONE`` ``PngImagePlugin.Disposal.OP_NONE``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND`` ``PngImagePlugin.Disposal.OP_BACKGROUND``
|
||||
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS`` ``PngImagePlugin.Disposal.OP_PREVIOUS``
|
||||
``PngImagePlugin.APNG_BLEND_OP_SOURCE`` ``PngImagePlugin.Blend.OP_SOURCE``
|
||||
``PngImagePlugin.APNG_BLEND_OP_OVER`` ``PngImagePlugin.Blend.OP_OVER``
|
||||
===================================================== ============================================================
|
||||
|
||||
FitsStubImagePlugin
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The stub image plugin ``FitsStubImagePlugin`` has been removed.
|
||||
FITS images can be read without a handler through :mod:`~PIL.FitsImagePlugin` instead.
|
||||
|
||||
FreeTypeFont.getmask2 fill parameter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The undocumented ``fill`` parameter of :py:meth:`.FreeTypeFont.getmask2` has been
|
||||
removed.
|
||||
|
||||
PhotoImage.paste box parameter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``box`` parameter was unused and has been removed.
|
||||
|
||||
PyQt5 and PySide2
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
`Qt 5 reached end-of-life <https://www.qt.io/blog/qt-5.15-released>`_ on 2020-12-08 for
|
||||
open-source users (and will reach EOL on 2023-12-08 for commercial licence holders).
|
||||
|
||||
Support for PyQt5 and PySide2 has been removed from ``ImageQt``. Upgrade to
|
||||
`PyQt6 <https://www.riverbankcomputing.com/static/Docs/PyQt6/>`_ or
|
||||
`PySide6 <https://doc.qt.io/qtforpython/>`_ instead.
|
||||
|
||||
Image.coerce_e
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This undocumented method has been removed.
|
||||
|
||||
Deprecations
|
||||
============
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
API Changes
|
||||
===========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
API Additions
|
||||
=============
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
||||
|
||||
Other Changes
|
||||
=============
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
|
||||
TODO
|
|
@ -8,7 +8,7 @@ JpegImagePlugin.convert_dict_qtables
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
JPEG ``quantization`` is now automatically converted, but still returned as a
|
||||
dictionary. The :py:attr:`~PIL.JpegImagePlugin.convert_dict_qtables` method no longer
|
||||
dictionary. The ``convert_dict_qtables`` method no longer
|
||||
performs any operations on the data given to it, has been deprecated and will be
|
||||
removed in Pillow 10.0.0 (2023-07-01).
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ expected to be backported to earlier versions.
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
10.0.0
|
||||
9.5.0
|
||||
9.4.0
|
||||
9.3.0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
x.y.z
|
||||
-----
|
||||
xx.y.z
|
||||
------
|
||||
|
||||
Backwards Incompatible Changes
|
||||
==============================
|
||||
|
|
4
setup.py
4
setup.py
|
@ -685,10 +685,6 @@ class pil_build_ext(build_ext):
|
|||
# Add the directory to the include path so we can include
|
||||
# <openjpeg.h> rather than having to cope with the versioned
|
||||
# include path
|
||||
# FIXME (melvyn-sopacua):
|
||||
# At this point it's possible that best_path is already in
|
||||
# self.compiler.include_dirs. Should investigate how that is
|
||||
# possible.
|
||||
_add_directory(self.compiler.include_dirs, best_path, 0)
|
||||
feature.jpeg2000 = "openjp2"
|
||||
feature.openjpeg_version = ".".join(str(x) for x in best_version)
|
||||
|
|
|
@ -35,7 +35,6 @@ from enum import IntEnum
|
|||
from io import BytesIO
|
||||
|
||||
from . import Image, ImageFile
|
||||
from ._deprecate import deprecate
|
||||
|
||||
|
||||
class Format(IntEnum):
|
||||
|
@ -54,21 +53,6 @@ class AlphaEncoding(IntEnum):
|
|||
DXT5 = 7
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
for enum, prefix in {
|
||||
Format: "BLP_FORMAT_",
|
||||
Encoding: "BLP_ENCODING_",
|
||||
AlphaEncoding: "BLP_ALPHA_ENCODING_",
|
||||
}.items():
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix) :]
|
||||
if name in enum.__members__:
|
||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||
return enum[name]
|
||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
||||
raise AttributeError(msg)
|
||||
|
||||
|
||||
def unpack_565(i):
|
||||
return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3
|
||||
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
#
|
||||
# The Python Imaging Library
|
||||
# $Id$
|
||||
#
|
||||
# FITS stub adapter
|
||||
#
|
||||
# Copyright (c) 1998-2003 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from . import FitsImagePlugin, Image, ImageFile
|
||||
from ._deprecate import deprecate
|
||||
|
||||
_handler = None
|
||||
|
||||
|
||||
def register_handler(handler):
|
||||
"""
|
||||
Install application-specific FITS image handler.
|
||||
|
||||
:param handler: Handler object.
|
||||
"""
|
||||
global _handler
|
||||
_handler = handler
|
||||
|
||||
deprecate(
|
||||
"FitsStubImagePlugin",
|
||||
10,
|
||||
action="FITS images can now be read without "
|
||||
"a handler through FitsImagePlugin instead",
|
||||
)
|
||||
|
||||
# Override FitsImagePlugin with this handler
|
||||
# for backwards compatibility
|
||||
try:
|
||||
Image.ID.remove(FITSStubImageFile.format)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
Image.register_open(
|
||||
FITSStubImageFile.format, FITSStubImageFile, FitsImagePlugin._accept
|
||||
)
|
||||
|
||||
|
||||
class FITSStubImageFile(ImageFile.StubImageFile):
|
||||
format = FitsImagePlugin.FitsImageFile.format
|
||||
format_description = FitsImagePlugin.FitsImageFile.format_description
|
||||
|
||||
def _open(self):
|
||||
offset = self.fp.tell()
|
||||
|
||||
im = FitsImagePlugin.FitsImageFile(self.fp)
|
||||
self._size = im.size
|
||||
self.mode = im.mode
|
||||
self.tile = []
|
||||
|
||||
self.fp.seek(offset)
|
||||
|
||||
loader = self._load()
|
||||
if loader:
|
||||
loader.open(self)
|
||||
|
||||
def _load(self):
|
||||
return _handler
|
||||
|
||||
|
||||
def _save(im, fp, filename):
|
||||
msg = "FITS save handler not installed"
|
||||
raise OSError(msg)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Registry
|
||||
|
||||
Image.register_save(FITSStubImageFile.format, _save)
|
|
@ -56,7 +56,6 @@ from enum import IntEnum
|
|||
from io import BytesIO
|
||||
|
||||
from . import Image, ImageFile
|
||||
from ._deprecate import deprecate
|
||||
|
||||
MAGIC = b"FTEX"
|
||||
|
||||
|
@ -66,17 +65,6 @@ class Format(IntEnum):
|
|||
UNCOMPRESSED = 1
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
for enum, prefix in {Format: "FORMAT_"}.items():
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix) :]
|
||||
if name in enum.__members__:
|
||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||
return enum[name]
|
||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
||||
raise AttributeError(msg)
|
||||
|
||||
|
||||
class FtexImageFile(ImageFile.ImageFile):
|
||||
format = "FTEX"
|
||||
format_description = "Texture File Format (IW2:EOC)"
|
||||
|
|
|
@ -56,29 +56,8 @@ from . import (
|
|||
_plugins,
|
||||
)
|
||||
from ._binary import i32le, o32be, o32le
|
||||
from ._deprecate import deprecate
|
||||
from ._util import DeferredError, is_path
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
categories = {"NORMAL": 0, "SEQUENCE": 1, "CONTAINER": 2}
|
||||
if name in categories:
|
||||
deprecate("Image categories", 10, "is_animated", plural=True)
|
||||
return categories[name]
|
||||
old_resampling = {
|
||||
"LINEAR": "BILINEAR",
|
||||
"CUBIC": "BICUBIC",
|
||||
"ANTIALIAS": "LANCZOS",
|
||||
}
|
||||
if name in old_resampling:
|
||||
deprecate(
|
||||
name, 10, f"{old_resampling[name]} or Resampling.{old_resampling[name]}"
|
||||
)
|
||||
return Resampling[old_resampling[name]]
|
||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
||||
raise AttributeError(msg)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -441,26 +420,18 @@ def _getencoder(mode, encoder_name, args, extra=()):
|
|||
# Simple expression analyzer
|
||||
|
||||
|
||||
def coerce_e(value):
|
||||
deprecate("coerce_e", 10)
|
||||
return value if isinstance(value, _E) else _E(1, value)
|
||||
|
||||
|
||||
# _E(scale, offset) represents the affine transformation scale * x + offset.
|
||||
# The "data" field is named for compatibility with the old implementation,
|
||||
# and should be renamed once coerce_e is removed.
|
||||
class _E:
|
||||
def __init__(self, scale, data):
|
||||
def __init__(self, scale, offset):
|
||||
self.scale = scale
|
||||
self.data = data
|
||||
self.offset = offset
|
||||
|
||||
def __neg__(self):
|
||||
return _E(-self.scale, -self.data)
|
||||
return _E(-self.scale, -self.offset)
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, _E):
|
||||
return _E(self.scale + other.scale, self.data + other.data)
|
||||
return _E(self.scale, self.data + other)
|
||||
return _E(self.scale + other.scale, self.offset + other.offset)
|
||||
return _E(self.scale, self.offset + other)
|
||||
|
||||
__radd__ = __add__
|
||||
|
||||
|
@ -473,19 +444,19 @@ class _E:
|
|||
def __mul__(self, other):
|
||||
if isinstance(other, _E):
|
||||
return NotImplemented
|
||||
return _E(self.scale * other, self.data * other)
|
||||
return _E(self.scale * other, self.offset * other)
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def __truediv__(self, other):
|
||||
if isinstance(other, _E):
|
||||
return NotImplemented
|
||||
return _E(self.scale / other, self.data / other)
|
||||
return _E(self.scale / other, self.offset / other)
|
||||
|
||||
|
||||
def _getscaleoffset(expr):
|
||||
a = expr(_E(1, 0))
|
||||
return (a.scale, a.data) if isinstance(a, _E) else (0, a)
|
||||
return (a.scale, a.offset) if isinstance(a, _E) else (0, a)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -516,17 +487,10 @@ class Image:
|
|||
self._size = (0, 0)
|
||||
self.palette = None
|
||||
self.info = {}
|
||||
self._category = 0
|
||||
self.readonly = 0
|
||||
self.pyaccess = None
|
||||
self._exif = None
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == "category":
|
||||
deprecate("Image categories", 10, "is_animated", plural=True)
|
||||
return self._category
|
||||
raise AttributeError(name)
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self.size[0]
|
||||
|
@ -639,7 +603,6 @@ class Image:
|
|||
and self.mode == other.mode
|
||||
and self.size == other.size
|
||||
and self.info == other.info
|
||||
and self._category == other._category
|
||||
and self.getpalette() == other.getpalette()
|
||||
and self.tobytes() == other.tobytes()
|
||||
)
|
||||
|
|
|
@ -20,8 +20,6 @@ from enum import IntEnum
|
|||
|
||||
from PIL import Image
|
||||
|
||||
from ._deprecate import deprecate
|
||||
|
||||
try:
|
||||
from PIL import _imagingcms
|
||||
except ImportError as ex:
|
||||
|
@ -117,17 +115,6 @@ class Direction(IntEnum):
|
|||
PROOF = 2
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
for enum, prefix in {Intent: "INTENT_", Direction: "DIRECTION_"}.items():
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix) :]
|
||||
if name in enum.__members__:
|
||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||
return enum[name]
|
||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
||||
raise AttributeError(msg)
|
||||
|
||||
|
||||
#
|
||||
# flags
|
||||
|
||||
|
|
|
@ -43,17 +43,6 @@ class Layout(IntEnum):
|
|||
RAQM = 1
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
for enum, prefix in {Layout: "LAYOUT_"}.items():
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix) :]
|
||||
if name in enum.__members__:
|
||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||
return enum[name]
|
||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
||||
raise AttributeError(msg)
|
||||
|
||||
|
||||
try:
|
||||
from . import _imagingft as core
|
||||
except ImportError as ex:
|
||||
|
@ -62,9 +51,6 @@ except ImportError as ex:
|
|||
core = DeferredError(ex)
|
||||
|
||||
|
||||
_UNSPECIFIED = object()
|
||||
|
||||
|
||||
# FIXME: add support for pilfont2 format (see FontFile.py)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -665,7 +651,6 @@ class FreeTypeFont:
|
|||
self,
|
||||
text,
|
||||
mode="",
|
||||
fill=_UNSPECIFIED,
|
||||
direction=None,
|
||||
features=None,
|
||||
language=None,
|
||||
|
@ -691,12 +676,6 @@ class FreeTypeFont:
|
|||
|
||||
.. versionadded:: 1.1.5
|
||||
|
||||
:param fill: Optional fill function. By default, an internal Pillow function
|
||||
will be used.
|
||||
|
||||
Deprecated. This parameter will be removed in Pillow 10
|
||||
(2023-07-01).
|
||||
|
||||
:param direction: Direction of the text. It can be 'rtl' (right to
|
||||
left), 'ltr' (left to right) or 'ttb' (top to bottom).
|
||||
Requires libraqm.
|
||||
|
@ -749,10 +728,6 @@ class FreeTypeFont:
|
|||
:py:mod:`PIL.Image.core` interface module, and the text offset, the
|
||||
gap between the starting coordinate and the first marking
|
||||
"""
|
||||
if fill is _UNSPECIFIED:
|
||||
fill = Image.core.fill
|
||||
else:
|
||||
deprecate("fill", 10)
|
||||
size, offset = self.font.getsize(
|
||||
text, mode, direction, features, language, anchor
|
||||
)
|
||||
|
@ -761,7 +736,7 @@ class FreeTypeFont:
|
|||
size = tuple(math.ceil(size[i] + stroke_width * 2 + start[i]) for i in range(2))
|
||||
offset = offset[0] - stroke_width, offset[1] - stroke_width
|
||||
Image._decompression_bomb_check(size)
|
||||
im = fill("RGBA" if mode == "RGBA" else "L", size, 0)
|
||||
im = Image.core.fill("RGBA" if mode == "RGBA" else "L", size, 0)
|
||||
if min(size):
|
||||
self.font.render(
|
||||
text,
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
import array
|
||||
|
||||
from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile
|
||||
from ._deprecate import deprecate
|
||||
|
||||
|
||||
class ImagePalette:
|
||||
|
@ -34,16 +33,11 @@ class ImagePalette:
|
|||
Defaults to an empty palette.
|
||||
"""
|
||||
|
||||
def __init__(self, mode="RGB", palette=None, size=0):
|
||||
def __init__(self, mode="RGB", palette=None):
|
||||
self.mode = mode
|
||||
self.rawmode = None # if set, palette contains raw data
|
||||
self.palette = palette or bytearray()
|
||||
self.dirty = None
|
||||
if size != 0:
|
||||
deprecate("The size parameter", 10, None)
|
||||
if size != len(self.palette):
|
||||
msg = "wrong palette size"
|
||||
raise ValueError(msg)
|
||||
|
||||
@property
|
||||
def palette(self):
|
||||
|
|
|
@ -20,14 +20,11 @@ import sys
|
|||
from io import BytesIO
|
||||
|
||||
from . import Image
|
||||
from ._deprecate import deprecate
|
||||
from ._util import is_path
|
||||
|
||||
qt_versions = [
|
||||
["6", "PyQt6"],
|
||||
["side6", "PySide6"],
|
||||
["5", "PyQt5"],
|
||||
["side2", "PySide2"],
|
||||
]
|
||||
|
||||
# If a version has already been imported, attempt it first
|
||||
|
@ -40,16 +37,6 @@ for qt_version, qt_module in qt_versions:
|
|||
elif qt_module == "PySide6":
|
||||
from PySide6.QtCore import QBuffer, QIODevice
|
||||
from PySide6.QtGui import QImage, QPixmap, qRgba
|
||||
elif qt_module == "PyQt5":
|
||||
from PyQt5.QtCore import QBuffer, QIODevice
|
||||
from PyQt5.QtGui import QImage, QPixmap, qRgba
|
||||
|
||||
deprecate("Support for PyQt5", 10, "PyQt6 or PySide6")
|
||||
elif qt_module == "PySide2":
|
||||
from PySide2.QtCore import QBuffer, QIODevice
|
||||
from PySide2.QtGui import QImage, QPixmap, qRgba
|
||||
|
||||
deprecate("Support for PySide2", 10, "PyQt6 or PySide6")
|
||||
except (ImportError, RuntimeError):
|
||||
continue
|
||||
qt_is_installed = True
|
||||
|
|
|
@ -19,8 +19,6 @@ from shlex import quote
|
|||
|
||||
from PIL import Image
|
||||
|
||||
from ._deprecate import deprecate
|
||||
|
||||
_viewers = []
|
||||
|
||||
|
||||
|
@ -111,21 +109,10 @@ class Viewer:
|
|||
"""Display the given image."""
|
||||
return self.show_file(self.save_image(image), **options)
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and will be removed in Pillow 10.0.0 (2023-07-01). ``path`` should be used
|
||||
instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
os.system(self.get_command(path, **options)) # nosec
|
||||
return 1
|
||||
|
||||
|
@ -164,21 +151,10 @@ class MacViewer(Viewer):
|
|||
command = f"({command} {quote(file)}; sleep 20; rm -f {quote(file)})&"
|
||||
return command
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and will be removed in Pillow 10.0.0 (2023-07-01). ``path`` should be used
|
||||
instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
subprocess.call(["open", "-a", "Preview.app", path])
|
||||
executable = sys.executable or shutil.which("python3")
|
||||
if executable:
|
||||
|
@ -215,21 +191,10 @@ class XDGViewer(UnixViewer):
|
|||
command = executable = "xdg-open"
|
||||
return command, executable
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and will be removed in Pillow 10.0.0 (2023-07-01). ``path`` should be used
|
||||
instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
subprocess.Popen(["xdg-open", path])
|
||||
return 1
|
||||
|
||||
|
@ -246,20 +211,10 @@ class DisplayViewer(UnixViewer):
|
|||
command += f" -title {quote(title)}"
|
||||
return command, executable
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and ``path`` should be used instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
args = ["display"]
|
||||
title = options.get("title")
|
||||
if title:
|
||||
|
@ -278,20 +233,10 @@ class GmDisplayViewer(UnixViewer):
|
|||
command = "gm display"
|
||||
return command, executable
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and ``path`` should be used instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
subprocess.Popen(["gm", "display", path])
|
||||
return 1
|
||||
|
||||
|
@ -304,20 +249,10 @@ class EogViewer(UnixViewer):
|
|||
command = "eog -n"
|
||||
return command, executable
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and ``path`` should be used instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
subprocess.Popen(["eog", "-n", path])
|
||||
return 1
|
||||
|
||||
|
@ -336,20 +271,10 @@ class XVViewer(UnixViewer):
|
|||
command += f" -name {quote(title)}"
|
||||
return command, executable
|
||||
|
||||
def show_file(self, path=None, **options):
|
||||
def show_file(self, path, **options):
|
||||
"""
|
||||
Display given file.
|
||||
|
||||
Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
|
||||
and ``path`` should be used instead.
|
||||
"""
|
||||
if path is None:
|
||||
if "file" in options:
|
||||
deprecate("The 'file' argument", 10, "'path'")
|
||||
path = options.pop("file")
|
||||
else:
|
||||
msg = "Missing required argument: 'path'"
|
||||
raise TypeError(msg)
|
||||
args = ["xv"]
|
||||
title = options.get("title")
|
||||
if title:
|
||||
|
|
|
@ -29,7 +29,6 @@ import tkinter
|
|||
from io import BytesIO
|
||||
|
||||
from . import Image
|
||||
from ._deprecate import deprecate
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Check for Tkinter interface hooks
|
||||
|
@ -162,7 +161,7 @@ class PhotoImage:
|
|||
"""
|
||||
return self.__size[1]
|
||||
|
||||
def paste(self, im, box=None):
|
||||
def paste(self, im):
|
||||
"""
|
||||
Paste a PIL image into the photo image. Note that this can
|
||||
be very slow if the photo image is displayed.
|
||||
|
@ -170,13 +169,7 @@ class PhotoImage:
|
|||
:param im: A PIL image. The size must match the target region. If the
|
||||
mode does not match, the image is converted to the mode of
|
||||
the bitmap image.
|
||||
:param box: Deprecated. This parameter will be removed in Pillow 10
|
||||
(2023-07-01).
|
||||
"""
|
||||
|
||||
if box is not None:
|
||||
deprecate("The box parameter", 10, None)
|
||||
|
||||
# convert to blittable
|
||||
im.load()
|
||||
image = im.im
|
||||
|
|
|
@ -46,7 +46,6 @@ from ._binary import i16be as i16
|
|||
from ._binary import i32be as i32
|
||||
from ._binary import o8
|
||||
from ._binary import o16be as o16
|
||||
from ._deprecate import deprecate
|
||||
from .JpegPresets import presets
|
||||
|
||||
#
|
||||
|
@ -612,11 +611,6 @@ samplings = {
|
|||
# fmt: on
|
||||
|
||||
|
||||
def convert_dict_qtables(qtables):
|
||||
deprecate("convert_dict_qtables", 10, action="Conversion is no longer needed")
|
||||
return qtables
|
||||
|
||||
|
||||
def get_sampling(im):
|
||||
# There's no subsampling when images have only 1 layer
|
||||
# (grayscale images) or when they are CMYK (4 layers),
|
||||
|
|
|
@ -66,9 +66,6 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
|||
self._n_frames = len(self.images)
|
||||
self.is_animated = self._n_frames > 1
|
||||
|
||||
if len(self.images) > 1:
|
||||
self._category = Image.CONTAINER
|
||||
|
||||
self.seek(0)
|
||||
|
||||
def seek(self, frame):
|
||||
|
|
|
@ -45,7 +45,6 @@ from ._binary import i32be as i32
|
|||
from ._binary import o8
|
||||
from ._binary import o16be as o16
|
||||
from ._binary import o32be as o32
|
||||
from ._deprecate import deprecate
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -131,17 +130,6 @@ class Blend(IntEnum):
|
|||
"""
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
for enum, prefix in {Disposal: "APNG_DISPOSE_", Blend: "APNG_BLEND_"}.items():
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix) :]
|
||||
if name in enum.__members__:
|
||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
||||
return enum[name]
|
||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
||||
raise AttributeError(msg)
|
||||
|
||||
|
||||
def _safe_zlib_decompress(s):
|
||||
dobj = zlib.decompressobj()
|
||||
plaintext = dobj.decompress(s, MAX_TEXT_CHUNK)
|
||||
|
|
|
@ -31,7 +31,6 @@ _plugins = [
|
|||
"DdsImagePlugin",
|
||||
"EpsImagePlugin",
|
||||
"FitsImagePlugin",
|
||||
"FitsStubImagePlugin",
|
||||
"FliImagePlugin",
|
||||
"FpxImagePlugin",
|
||||
"FtexImagePlugin",
|
||||
|
|
|
@ -4,8 +4,6 @@ import sys
|
|||
import tkinter
|
||||
from tkinter import _tkinter as tk
|
||||
|
||||
from ._deprecate import deprecate
|
||||
|
||||
try:
|
||||
if hasattr(sys, "pypy_find_executable"):
|
||||
TKINTER_LIB = tk.tklib_cffi.__file__
|
||||
|
@ -17,7 +15,3 @@ except AttributeError:
|
|||
TKINTER_LIB = None
|
||||
|
||||
tk_version = str(tkinter.TkVersion)
|
||||
if tk_version == "8.4":
|
||||
deprecate(
|
||||
"Support for Tk/Tcl 8.4", 10, action="Please upgrade to Tk/Tcl 8.5 or newer"
|
||||
)
|
||||
|
|
|
@ -119,17 +119,7 @@ typedef struct Tk_PhotoImageBlock {
|
|||
} Tk_PhotoImageBlock;
|
||||
|
||||
/* Typedefs derived from function signatures in Tk header */
|
||||
/* Tk_PhotoPutBlock for Tk <= 8.4 */
|
||||
typedef void (*Tk_PhotoPutBlock_84_t)(
|
||||
Tk_PhotoHandle handle,
|
||||
Tk_PhotoImageBlock *blockPtr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int compRule);
|
||||
/* Tk_PhotoPutBlock for Tk >= 8.5 */
|
||||
typedef int (*Tk_PhotoPutBlock_85_t)(
|
||||
typedef int (*Tk_PhotoPutBlock_t)(
|
||||
Tcl_Interp *interp,
|
||||
Tk_PhotoHandle handle,
|
||||
Tk_PhotoImageBlock *blockPtr,
|
||||
|
@ -138,8 +128,6 @@ typedef int (*Tk_PhotoPutBlock_85_t)(
|
|||
int width,
|
||||
int height,
|
||||
int compRule);
|
||||
/* Tk_PhotoSetSize for Tk <= 8.4 */
|
||||
typedef void (*Tk_PhotoSetSize_84_t)(Tk_PhotoHandle handle, int width, int height);
|
||||
/* Tk_FindPhoto */
|
||||
typedef Tk_PhotoHandle (*Tk_FindPhoto_t)(Tcl_Interp *interp, const char *imageName);
|
||||
/* Tk_PhotoGetImage */
|
||||
|
|
|
@ -48,14 +48,11 @@
|
|||
* Global vars for Tcl / Tk functions. We load these symbols from the tkinter
|
||||
* extension module or loaded Tcl / Tk libraries at run-time.
|
||||
*/
|
||||
static int TK_LT_85 = 0;
|
||||
static Tcl_CreateCommand_t TCL_CREATE_COMMAND;
|
||||
static Tcl_AppendResult_t TCL_APPEND_RESULT;
|
||||
static Tk_FindPhoto_t TK_FIND_PHOTO;
|
||||
static Tk_PhotoGetImage_t TK_PHOTO_GET_IMAGE;
|
||||
static Tk_PhotoPutBlock_84_t TK_PHOTO_PUT_BLOCK_84;
|
||||
static Tk_PhotoSetSize_84_t TK_PHOTO_SET_SIZE_84;
|
||||
static Tk_PhotoPutBlock_85_t TK_PHOTO_PUT_BLOCK_85;
|
||||
static Tk_PhotoPutBlock_t TK_PHOTO_PUT_BLOCK;
|
||||
|
||||
static Imaging
|
||||
ImagingFind(const char *name) {
|
||||
|
@ -130,26 +127,15 @@ PyImagingPhotoPut(
|
|||
block.pitch = im->linesize;
|
||||
block.pixelPtr = (unsigned char *)im->block;
|
||||
|
||||
if (TK_LT_85) { /* Tk 8.4 */
|
||||
TK_PHOTO_PUT_BLOCK_84(
|
||||
photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET);
|
||||
if (strcmp(im->mode, "RGBA") == 0) {
|
||||
/* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
|
||||
/* (fixed in Tk 8.5a3) */
|
||||
TK_PHOTO_SET_SIZE_84(photo, block.width, block.height);
|
||||
}
|
||||
} else {
|
||||
/* Tk >=8.5 */
|
||||
TK_PHOTO_PUT_BLOCK_85(
|
||||
interp,
|
||||
photo,
|
||||
&block,
|
||||
0,
|
||||
0,
|
||||
block.width,
|
||||
block.height,
|
||||
TK_PHOTO_COMPOSITE_SET);
|
||||
}
|
||||
TK_PHOTO_PUT_BLOCK(
|
||||
interp,
|
||||
photo,
|
||||
&block,
|
||||
0,
|
||||
0,
|
||||
block.width,
|
||||
block.height,
|
||||
TK_PHOTO_COMPOSITE_SET);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
@ -290,16 +276,7 @@ get_tk(HMODULE hMod) {
|
|||
if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(hMod, "Tk_FindPhoto")) == NULL) {
|
||||
return -1;
|
||||
};
|
||||
TK_LT_85 = GetProcAddress(hMod, "Tk_PhotoPutBlock_Panic") == NULL;
|
||||
/* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
|
||||
if (TK_LT_85) {
|
||||
TK_PHOTO_PUT_BLOCK_84 = (Tk_PhotoPutBlock_84_t)func;
|
||||
return ((TK_PHOTO_SET_SIZE_84 =
|
||||
(Tk_PhotoSetSize_84_t)_dfunc(hMod, "Tk_PhotoSetSize")) == NULL)
|
||||
? -1
|
||||
: 1;
|
||||
}
|
||||
TK_PHOTO_PUT_BLOCK_85 = (Tk_PhotoPutBlock_85_t)func;
|
||||
TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)func;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -422,18 +399,9 @@ _func_loader(void *lib) {
|
|||
if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(lib, "Tk_FindPhoto")) == NULL) {
|
||||
return 1;
|
||||
}
|
||||
/* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
|
||||
TK_LT_85 = (dlsym(lib, "Tk_PhotoPutBlock_Panic") == NULL);
|
||||
if (TK_LT_85) {
|
||||
return (
|
||||
((TK_PHOTO_PUT_BLOCK_84 =
|
||||
(Tk_PhotoPutBlock_84_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL) ||
|
||||
((TK_PHOTO_SET_SIZE_84 =
|
||||
(Tk_PhotoSetSize_84_t)_dfunc(lib, "Tk_PhotoSetSize")) == NULL));
|
||||
}
|
||||
return (
|
||||
(TK_PHOTO_PUT_BLOCK_85 =
|
||||
(Tk_PhotoPutBlock_85_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL);
|
||||
(TK_PHOTO_PUT_BLOCK =
|
||||
(Tk_PhotoPutBlock_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in New Issue
Block a user