From 59c9d87f8a4d8443a482ca7abb5f1f8d5d970cbd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 2 Apr 2023 00:27:22 +0300 Subject: [PATCH] Remove support for PyQt5 and PySide2, deprecated in 9.2.0 --- .github/workflows/test-cygwin.yml | 2 +- Tests/test_deprecated_imageqt.py | 18 ------------------ Tests/test_imageqt.py | 11 ++--------- Tests/test_qt_image_qapplication.py | 14 +------------- Tests/test_qt_image_toqimage.py | 6 +----- docs/deprecations.rst | 26 +++++++++++++------------- docs/reference/ImageQt.rst | 14 +++----------- src/PIL/ImageQt.py | 13 ------------- 8 files changed, 21 insertions(+), 83 deletions(-) delete mode 100644 Tests/test_deprecated_imageqt.py diff --git a/.github/workflows/test-cygwin.yml b/.github/workflows/test-cygwin.yml index 6c9ed66e3..397cfe0a1 100644 --- a/.github/workflows/test-cygwin.yml +++ b/.github/workflows/test-cygwin.yml @@ -67,7 +67,7 @@ jobs: python3${{ matrix.python-minor-version }}-numpy python3${{ matrix.python-minor-version }}-sip python3${{ matrix.python-minor-version }}-tkinter - qt5-devel-tools + qt6-devel-tools wget xorg-server-extra zlib-devel diff --git a/Tests/test_deprecated_imageqt.py b/Tests/test_deprecated_imageqt.py deleted file mode 100644 index 2528ff3f7..000000000 --- a/Tests/test_deprecated_imageqt.py +++ /dev/null @@ -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 diff --git a/Tests/test_imageqt.py b/Tests/test_imageqt.py index 2f2b07918..2c73a2094 100644 --- a/Tests/test_imageqt.py +++ b/Tests/test_imageqt.py @@ -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) diff --git a/Tests/test_qt_image_qapplication.py b/Tests/test_qt_image_qapplication.py index 4929fa933..5d2e41212 100644 --- a/Tests/test_qt_image_qapplication.py +++ b/Tests/test_qt_image_qapplication.py @@ -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): diff --git a/Tests/test_qt_image_toqimage.py b/Tests/test_qt_image_toqimage.py index c1983031a..399df670f 100644 --- a/Tests/test_qt_image_toqimage.py +++ b/Tests/test_qt_image_toqimage.py @@ -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 diff --git a/docs/deprecations.rst b/docs/deprecations.rst index 5669d2827..48e8b6d93 100644 --- a/docs/deprecations.rst +++ b/docs/deprecations.rst @@ -135,19 +135,6 @@ PhotoImage.paste box parameter 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 `_ 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 `_ or -`PySide6 `_ instead. - Image.coerce_e ~~~~~~~~~~~~~~ @@ -223,6 +210,19 @@ Removed features Deprecated features are only removed in major releases after an appropriate period of deprecation has passed. +PyQt5 and PySide2 +~~~~~~~~~~~~~~~~~ + +.. deprecated:: 9.2.0 +.. versionremoved:: 10.0.0 + +`Qt 5 reached end-of-life `_ 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 `_ or +`PySide6 `_ instead. + PILLOW_VERSION constant ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/reference/ImageQt.rst b/docs/reference/ImageQt.rst index 15d052d1c..7e67a44d3 100644 --- a/docs/reference/ImageQt.rst +++ b/docs/reference/ImageQt.rst @@ -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 `_ 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 `_ or -`PySide6 `_ 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. diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py index ad607a97b..9b7245454 100644 --- a/src/PIL/ImageQt.py +++ b/src/PIL/ImageQt.py @@ -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