Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Tests/test_deprecate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"version, expected",
[
(
13,
"Old thing is deprecated and will be removed in Pillow 13 "
r"\(2026-10-15\)\. Use new thing instead\.",
14,
"Old thing is deprecated and will be removed in Pillow 14 "
r"\(2027-10-15\)\. Use new thing instead\.",
),
(
None,
Expand Down Expand Up @@ -53,18 +53,18 @@ def test_old_version(deprecated: str, plural: bool, expected: str) -> None:

def test_plural() -> None:
expected = (
r"Old things are deprecated and will be removed in Pillow 13 \(2026-10-15\)\. "
r"Old things are deprecated and will be removed in Pillow 14 \(2027-10-15\)\. "
r"Use new thing instead\."
)
with pytest.warns(DeprecationWarning, match=expected):
_deprecate.deprecate("Old things", 13, "new thing", plural=True)
_deprecate.deprecate("Old things", 14, "new thing", plural=True)


def test_replacement_and_action() -> None:
expected = "Use only one of 'replacement' and 'action'"
with pytest.raises(ValueError, match=expected):
_deprecate.deprecate(
"Old thing", 13, replacement="new thing", action="Upgrade to new thing"
"Old thing", 14, replacement="new thing", action="Upgrade to new thing"
)


Expand All @@ -77,16 +77,16 @@ def test_replacement_and_action() -> None:
)
def test_action(action: str) -> None:
expected = (
r"Old thing is deprecated and will be removed in Pillow 13 \(2026-10-15\)\. "
r"Old thing is deprecated and will be removed in Pillow 14 \(2027-10-15\)\. "
r"Upgrade to new thing\."
)
with pytest.warns(DeprecationWarning, match=expected):
_deprecate.deprecate("Old thing", 13, action=action)
_deprecate.deprecate("Old thing", 14, action=action)


def test_no_replacement_or_action() -> None:
expected = (
r"Old thing is deprecated and will be removed in Pillow 13 \(2026-10-15\)"
r"Old thing is deprecated and will be removed in Pillow 14 \(2027-10-15\)"
)
with pytest.warns(DeprecationWarning, match=expected):
_deprecate.deprecate("Old thing", 13)
_deprecate.deprecate("Old thing", 14)
15 changes: 0 additions & 15 deletions Tests/test_file_png.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,11 +537,6 @@ def test_trns_invalid(self, tmp_path: Path) -> None:
):
im.save(out, transparency="invalid")

im = Image.new("I", (1, 1))
with pytest.warns(DeprecationWarning, match="Saving I mode images as PNG"):
with pytest.raises(ValueError):
im.save(out, transparency="invalid")

im = Image.new("P", (1, 1))
with pytest.raises(
ValueError, match="transparency for P must be an integer or bytes"
Expand Down Expand Up @@ -880,16 +875,6 @@ def test_truncated_end_chunk(self, monkeypatch: pytest.MonkeyPatch) -> None:
with Image.open("Tests/images/truncated_end_chunk.png") as im:
assert_image_equal_tofile(im, "Tests/images/hopper.png")

def test_deprecation(self, tmp_path: Path) -> None:
test_file = tmp_path / "out.png"

im = hopper("I")
with pytest.warns(DeprecationWarning, match="Saving I mode images as PNG"):
im.save(test_file)

with Image.open(test_file) as reloaded:
assert_image_equal(im, reloaded.convert("I"))


@pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
@skip_unless_feature("zlib")
Expand Down
13 changes: 0 additions & 13 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
ImageDraw,
ImageFile,
ImagePalette,
ImageShow,
UnidentifiedImageError,
features,
)
Expand Down Expand Up @@ -1024,18 +1023,6 @@ def test_getxmp_padded(self) -> None:
else:
assert im.getxmp() == {"xmpmeta": None}

def test_get_child_images(self) -> None:
im = Image.new("RGB", (1, 1))
with pytest.warns(DeprecationWarning, match="Image.Image.get_child_images"):
assert im.get_child_images() == []

def test_show(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(ImageShow, "_viewers", [])

im = Image.new("RGB", (1, 1))
with pytest.warns(DeprecationWarning, match="Image._show"):
Image._show(im)

@pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
def test_zero_tobytes(self, size: tuple[int, int]) -> None:
im = Image.new("RGB", size)
Expand Down
8 changes: 0 additions & 8 deletions Tests/test_image_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,3 @@ def test_fromarray_palette() -> None:
# Assert that the Python and C palettes match
assert out.palette is not None
assert len(out.palette.colors) == len(out.im.getpalette()) / 3


def test_deprecation() -> None:
a = numpy.array(im.convert("L"))
with pytest.warns(
DeprecationWarning, match="'mode' parameter for changing data types"
):
Image.fromarray(a, "1")
14 changes: 0 additions & 14 deletions Tests/test_imagecms.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,17 +698,3 @@ def test_cmyk_lab() -> None:
im = Image.new("CMYK", (1, 1))
converted_im = im.convert("LAB")
assert converted_im.getpixel((0, 0)) == (255, 128, 128)


def test_deprecation() -> None:
profile = ImageCmsProfile(ImageCms.createProfile("sRGB"))
with pytest.warns(
DeprecationWarning, match="ImageCms.ImageCmsProfile.product_name"
):
profile.product_name
with pytest.warns(
DeprecationWarning, match="ImageCms.ImageCmsProfile.product_info"
):
profile.product_info
with pytest.raises(AttributeError):
profile.this_attribute_does_not_exist
95 changes: 50 additions & 45 deletions docs/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,74 +20,79 @@ ExifTags.IFD.Makernote
``ExifTags.IFD.Makernote`` has been deprecated. Instead, use
``ExifTags.IFD.MakerNote``.

Image.Image.get_child_images()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Image getdata()
~~~~~~~~~~~~~~~

.. deprecated:: 11.2.1
.. deprecated:: 12.1.0

``Image.Image.get_child_images()`` has been deprecated, and will be removed in Pillow
13 (2026-10-15). It will be moved to ``ImageFile.ImageFile.get_child_images()``. The
method uses an image's file pointer, and so child images could only be retrieved from
an :py:class:`PIL.ImageFile.ImageFile` instance.
:py:meth:`~PIL.Image.Image.getdata` has been deprecated.
:py:meth:`~PIL.Image.Image.get_flattened_data` can be used instead. This new method is
identical, except that it returns a tuple of pixel values, instead of an internal
Pillow data type.

Image.fromarray mode parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Removed features
----------------

.. deprecated:: 11.3.0
Deprecated features are only removed in major releases after an appropriate
period of deprecation has passed.

Using the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was deprecated in
Pillow 11.3.0. In Pillow 12.0.0, this was partially reverted, and it is now only
deprecated when changing data types. Since pixel values do not contain information
about palettes or color spaces, the parameter can still be used to place grayscale L
mode data within a P mode image, or read RGB data as YCbCr for example. If omitted, the
mode will be automatically determined from the object's shape and type.
Image._show
^^^^^^^^^^^

.. deprecated:: 12.0.0
.. versionremoved:: 13.0.0

``Image._show`` has been removed. Use :py:meth:`~PIL.ImageShow.show` instead.

ImageCms.ImageCmsProfile.product_name and .product_info
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 12.0.0
.. versionremoved:: 13.0.0

``ImageCms.ImageCmsProfile.product_name`` and the corresponding
``.product_info`` attributes have been removed. They were set to ``None`` since Pillow
2.3.0.

Saving I mode images as PNG
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.3.0
.. versionremoved:: 13.0.0

In order to fit the 32 bits of I mode images into PNG, when PNG images can only contain
at most 16 bits for a channel, Pillow has been clipping the values. Rather than quietly
changing the data, this is now deprecated. Instead, the image can be converted to
another mode before saving::
changing the data, this is now removed. Instead, the image can be converted to another
mode before saving::

from PIL import Image
im = Image.new("I", (1, 1))
im.convert("I;16").save("out.png")

ImageCms.ImageCmsProfile.product_name and .product_info
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 12.0.0

``ImageCms.ImageCmsProfile.product_name`` and the corresponding
``.product_info`` attributes have been deprecated, and will be removed in
Pillow 13 (2026-10-15). They have been set to ``None`` since Pillow 2.3.0.

Image._show
~~~~~~~~~~~

.. deprecated:: 12.0.0

``Image._show`` has been deprecated, and will be removed in Pillow 13 (2026-10-15).
Use :py:meth:`~PIL.ImageShow.show` instead.
Image.fromarray mode parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Image getdata()
~~~~~~~~~~~~~~~
.. deprecated:: 11.3.0
.. versionremoved:: 13.0.0

.. deprecated:: 12.1.0
Using the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was deprecated in
Pillow 11.3.0. In Pillow 12.0.0, this was partially reverted, and now the only
functionality removed is when the mode changes data types. Since pixel values do not
contain information about palettes or color spaces, the parameter can still be used to
place grayscale L mode data within a P mode image, or read RGB data as YCbCr for
example. If omitted, the mode will be automatically determined from the object's shape
and type.

:py:meth:`~PIL.Image.Image.getdata` has been deprecated.
:py:meth:`~PIL.Image.Image.get_flattened_data` can be used instead. This new method is
identical, except that it returns a tuple of pixel values, instead of an internal
Pillow data type.
Image.Image.get_child_images()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Removed features
----------------
.. deprecated:: 11.2.1
.. versionremoved:: 13.0.0

Deprecated features are only removed in major releases after an appropriate
period of deprecation has passed.
``Image.Image.get_child_images()`` has been moved to
``ImageFile.ImageFile.get_child_images()``. The method uses an image's file pointer,
and so child images could only be retrieved from an :py:class:`PIL.ImageFile.ImageFile`
instance.

ImageFile.raise_oserror
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
93 changes: 93 additions & 0 deletions docs/releasenotes/13.0.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
13.0.0
------

Security
========

TODO
^^^^

TODO

:cve:`YYYY-XXXXX`: TODO
^^^^^^^^^^^^^^^^^^^^^^^

TODO

Backwards incompatible changes
==============================

Saving I mode images as PNG
^^^^^^^^^^^^^^^^^^^^^^^^^^^

In order to fit the 32 bits of I mode images into PNG, when PNG images can only contain
at most 16 bits for a channel, Pillow has been clipping the values. Rather than quietly
changing the data, this is now removed. Instead, the image can be converted to another
mode before saving::

from PIL import Image
im = Image.new("I", (1, 1))
im.convert("I;16").save("out.png")

Image.fromarray mode parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Using the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was deprecated in
Pillow 11.3.0. In Pillow 12.0.0, this was partially reverted, and now the only
functionality removed is when the mode changes data types. Since pixel values do not
contain information about palettes or color spaces, the parameter can still be used to
place grayscale L mode data within a P mode image, or read RGB data as YCbCr for
example. If omitted, the mode will be automatically determined from the object's shape
and type.

Image.Image.get_child_images()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``Image.Image.get_child_images()`` has been moved to
``ImageFile.ImageFile.get_child_images()``. The method uses an image's file pointer,
and so child images could only be retrieved from an :py:class:`PIL.ImageFile.ImageFile`
instance.

Image._show
~~~~~~~~~~~

``Image._show`` has been removed. Use :py:meth:`~PIL.ImageShow.show` instead.

ImageCms.ImageCmsProfile.product_name and .product_info
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``ImageCms.ImageCmsProfile.product_name`` and the corresponding
``.product_info`` attributes have been removed. They were set to ``None`` since Pillow
2.3.0.

Deprecations
============

TODO
^^^^

TODO

API changes
===========

TODO
^^^^

TODO

API additions
=============

TODO
^^^^

TODO

Other changes
=============

TODO
^^^^

TODO
1 change: 1 addition & 0 deletions docs/releasenotes/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ expected to be backported to earlier versions.
:maxdepth: 2

versioning
13.0.0
12.3.0
12.2.0
12.1.1
Expand Down
Loading
Loading