[Python-checkins] gh-104773: PEP 594: Remove the imghdr module (#104777)

vstinner webhook-mailer at python.org
Fri May 26 09:29:52 EDT 2023


https://github.com/python/cpython/commit/e399f46a77263621610b350453e0f50252c6dc08
commit: e399f46a77263621610b350453e0f50252c6dc08
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2023-05-26T13:29:45Z
summary:

gh-104773: PEP 594: Remove the imghdr module (#104777)

* Remove the Lib/test/imghdrdata/ directory.
* Copy 5 pictures (gif, png, ppm, pgm, xbm) from removed
  Lib/test/imghdrdata/ to a new Lib/test/tkinterdata/ directory.
* Update Sphinx from 4.5 to 6.2 in Doc/requirements.txt.

files:
A Lib/test/tkinterdata/python.gif
A Lib/test/tkinterdata/python.pgm
A Lib/test/tkinterdata/python.png
A Lib/test/tkinterdata/python.ppm
A Lib/test/tkinterdata/python.xbm
A Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst
D Doc/library/imghdr.rst
D Lib/imghdr.py
D Lib/test/imghdrdata/python-raw.jpg
D Lib/test/imghdrdata/python.bmp
D Lib/test/imghdrdata/python.exr
D Lib/test/imghdrdata/python.gif
D Lib/test/imghdrdata/python.jpg
D Lib/test/imghdrdata/python.pbm
D Lib/test/imghdrdata/python.pgm
D Lib/test/imghdrdata/python.png
D Lib/test/imghdrdata/python.ppm
D Lib/test/imghdrdata/python.ras
D Lib/test/imghdrdata/python.sgi
D Lib/test/imghdrdata/python.tiff
D Lib/test/imghdrdata/python.webp
D Lib/test/imghdrdata/python.xbm
D Lib/test/test_imghdr.py
M Doc/library/superseded.rst
M Doc/requirements.txt
M Doc/whatsnew/3.11.rst
M Doc/whatsnew/3.12.rst
M Doc/whatsnew/3.13.rst
M Doc/whatsnew/3.5.rst
M Lib/test/test_tkinter/test_images.py
M Lib/test/test_tkinter/widget_tests.py
M Makefile.pre.in
M Python/stdlib_module_names.h

diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst
deleted file mode 100644
index 630fd7019f94d..0000000000000
--- a/Doc/library/imghdr.rst
+++ /dev/null
@@ -1,86 +0,0 @@
-:mod:`imghdr` --- Determine the type of an image
-================================================
-
-.. module:: imghdr
-   :synopsis: Determine the type of image contained in a file or byte stream.
-   :deprecated:
-
-**Source code:** :source:`Lib/imghdr.py`
-
-.. deprecated-removed:: 3.11 3.13
-   The :mod:`imghdr` module is deprecated
-   (see :pep:`PEP 594 <594#imghdr>` for details and alternatives).
-
---------------
-
-The :mod:`imghdr` module determines the type of image contained in a file or
-byte stream.
-
-The :mod:`imghdr` module defines the following function:
-
-
-.. function:: what(file, h=None)
-
-   Test the image data contained in the file named *file* and return a
-   string describing the image type.  If *h* is provided, the *file*
-   argument is ignored and *h* is assumed to contain the byte stream to test.
-
-   .. versionchanged:: 3.6
-      Accepts a :term:`path-like object`.
-
-The following image types are recognized, as listed below with the return value
-from :func:`what`:
-
-+------------+-----------------------------------+
-| Value      | Image format                      |
-+============+===================================+
-| ``'rgb'``  | SGI ImgLib Files                  |
-+------------+-----------------------------------+
-| ``'gif'``  | GIF 87a and 89a Files             |
-+------------+-----------------------------------+
-| ``'pbm'``  | Portable Bitmap Files             |
-+------------+-----------------------------------+
-| ``'pgm'``  | Portable Graymap Files            |
-+------------+-----------------------------------+
-| ``'ppm'``  | Portable Pixmap Files             |
-+------------+-----------------------------------+
-| ``'tiff'`` | TIFF Files                        |
-+------------+-----------------------------------+
-| ``'rast'`` | Sun Raster Files                  |
-+------------+-----------------------------------+
-| ``'xbm'``  | X Bitmap Files                    |
-+------------+-----------------------------------+
-| ``'jpeg'`` | JPEG data in JFIF or Exif formats |
-+------------+-----------------------------------+
-| ``'bmp'``  | BMP files                         |
-+------------+-----------------------------------+
-| ``'png'``  | Portable Network Graphics         |
-+------------+-----------------------------------+
-| ``'webp'`` | WebP files                        |
-+------------+-----------------------------------+
-| ``'exr'``  | OpenEXR Files                     |
-+------------+-----------------------------------+
-
-.. versionadded:: 3.5
-   The *exr* and *webp* formats were added.
-
-
-You can extend the list of file types :mod:`imghdr` can recognize by appending
-to this variable:
-
-
-.. data:: tests
-
-   A list of functions performing the individual tests.  Each function takes two
-   arguments: the byte-stream and an open file-like object. When :func:`what` is
-   called with a byte-stream, the file-like object will be ``None``.
-
-   The test function should return a string describing the image type if the test
-   succeeded, or ``None`` if it failed.
-
-Example::
-
-   >>> import imghdr
-   >>> imghdr.what('bass.gif')
-   'gif'
-
diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst
index 24e74110a319f..bd17039bc6f6b 100644
--- a/Doc/library/superseded.rst
+++ b/Doc/library/superseded.rst
@@ -10,5 +10,4 @@ backwards compatibility. They have been superseded by other modules.
 
 .. toctree::
 
-   imghdr.rst
    optparse.rst
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index 9cbd15c2209dc..d3fa6ce6dabc6 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -6,7 +6,8 @@
 # Sphinx version is pinned so that new versions that introduce new warnings
 # won't suddenly cause build failures. Updating the version is fine as long
 # as no warnings are raised by doing so.
-sphinx==4.5.0
+# PR #104777: Sphinx 6.2 no longer uses imghdr, removed in Python 3.13.
+sphinx==6.2.0
 
 blurb
 
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 7186ba5521f95..066070eda7dba 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -1735,7 +1735,7 @@ Modules
   +---------------------+---------------------+---------------------+---------------------+---------------------+
   | :mod:`!audioop`     | :mod:`!crypt`       | :mod:`!nis`         | :mod:`!sndhdr`      | :mod:`!uu`          |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
-  | :mod:`!cgi`         | :mod:`imghdr`       | :mod:`!nntplib`     | :mod:`!spwd`        | :mod:`!xdrlib`      |
+  | :mod:`!cgi`         | :mod:`!imghdr`      | :mod:`!nntplib`     | :mod:`!spwd`        | :mod:`!xdrlib`      |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
   | :mod:`!cgitb`       | :mod:`!mailcap`     | :mod:`!ossaudiodev` | :mod:`!sunau`       |                     |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 5266f5ffb9373..c8fd77f0fdb4a 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -924,7 +924,7 @@ Modules (see :pep:`594`):
 * :mod:`!cgitb`
 * :mod:`!chunk`
 * :mod:`!crypt`
-* :mod:`imghdr`
+* :mod:`!imghdr`
 * :mod:`!mailcap`
 * :mod:`!msilib`
 * :mod:`!nis`
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 0e78a080c4304..28c98554fdbfd 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -244,6 +244,14 @@ Removed
   :class:`typing.TypedDict` types, deprecated in Python 3.11.
   (Contributed by Tomas Roun in :gh:`104786`.)
 
+* :pep:`594`: Remove the :mod:`!imghdr` module, deprecated in Python 3.11:
+  use the projects
+  `filetype <https://pypi.org/project/filetype/>`_,
+  `puremagic <https://pypi.org/project/puremagic/>`_,
+  or `python-magic <https://pypi.org/project/python-magic/>`_ instead.
+  (Contributed by Victor Stinner in :gh:`104773`.)
+
+
 Porting to Python 3.13
 ======================
 
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
index cd8f6e2cd9b59..ccf71bf08e860 100644
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -1252,7 +1252,7 @@ Oberkirch in :issue:`21800`.)
 imghdr
 ------
 
-The :func:`~imghdr.what` function now recognizes the
+The :func:`~!imghdr.what` function now recognizes the
 `OpenEXR <https://www.openexr.com>`_ format
 (contributed by Martin Vignali and Claudiu Popa in :issue:`20295`),
 and the `WebP <https://en.wikipedia.org/wiki/WebP>`_ format
diff --git a/Lib/imghdr.py b/Lib/imghdr.py
deleted file mode 100644
index 3386888347076..0000000000000
--- a/Lib/imghdr.py
+++ /dev/null
@@ -1,180 +0,0 @@
-"""Recognize image file formats based on their first few bytes."""
-
-from os import PathLike
-import warnings
-
-__all__ = ["what"]
-
-
-warnings._deprecated(__name__, remove=(3, 13))
-
-
-#-------------------------#
-# Recognize image headers #
-#-------------------------#
-
-def what(file, h=None):
-    """Return the type of image contained in a file or byte stream."""
-    f = None
-    try:
-        if h is None:
-            if isinstance(file, (str, PathLike)):
-                f = open(file, 'rb')
-                h = f.read(32)
-            else:
-                location = file.tell()
-                h = file.read(32)
-                file.seek(location)
-        for tf in tests:
-            res = tf(h, f)
-            if res:
-                return res
-    finally:
-        if f: f.close()
-    return None
-
-
-#---------------------------------#
-# Subroutines per image file type #
-#---------------------------------#
-
-tests = []
-
-def test_jpeg(h, f):
-    """Test for JPEG data with JFIF or Exif markers; and raw JPEG."""
-    if h[6:10] in (b'JFIF', b'Exif'):
-        return 'jpeg'
-    elif h[:4] == b'\xff\xd8\xff\xdb':
-        return 'jpeg'
-
-tests.append(test_jpeg)
-
-def test_png(h, f):
-    """Verify if the image is a PNG."""
-    if h.startswith(b'\211PNG\r\n\032\n'):
-        return 'png'
-
-tests.append(test_png)
-
-def test_gif(h, f):
-    """Verify if the image is a GIF ('87 or '89 variants)."""
-    if h[:6] in (b'GIF87a', b'GIF89a'):
-        return 'gif'
-
-tests.append(test_gif)
-
-def test_tiff(h, f):
-    """Verify if the image is a TIFF (can be in Motorola or Intel byte order)."""
-    if h[:2] in (b'MM', b'II'):
-        return 'tiff'
-
-tests.append(test_tiff)
-
-def test_rgb(h, f):
-    """test for the SGI image library."""
-    if h.startswith(b'\001\332'):
-        return 'rgb'
-
-tests.append(test_rgb)
-
-def test_pbm(h, f):
-    """Verify if the image is a PBM (portable bitmap)."""
-    if len(h) >= 3 and \
-        h[0] == ord(b'P') and h[1] in b'14' and h[2] in b' \t\n\r':
-        return 'pbm'
-
-tests.append(test_pbm)
-
-def test_pgm(h, f):
-    """Verify if the image is a PGM (portable graymap)."""
-    if len(h) >= 3 and \
-        h[0] == ord(b'P') and h[1] in b'25' and h[2] in b' \t\n\r':
-        return 'pgm'
-
-tests.append(test_pgm)
-
-def test_ppm(h, f):
-    """Verify if the image is a PPM (portable pixmap)."""
-    if len(h) >= 3 and \
-        h[0] == ord(b'P') and h[1] in b'36' and h[2] in b' \t\n\r':
-        return 'ppm'
-
-tests.append(test_ppm)
-
-def test_rast(h, f):
-    """test for the Sun raster file."""
-    if h.startswith(b'\x59\xA6\x6A\x95'):
-        return 'rast'
-
-tests.append(test_rast)
-
-def test_xbm(h, f):
-    """Verify if the image is a X bitmap (X10 or X11)."""
-    if h.startswith(b'#define '):
-        return 'xbm'
-
-tests.append(test_xbm)
-
-def test_bmp(h, f):
-    """Verify if the image is a BMP file."""
-    if h.startswith(b'BM'):
-        return 'bmp'
-
-tests.append(test_bmp)
-
-def test_webp(h, f):
-    """Verify if the image is a WebP."""
-    if h.startswith(b'RIFF') and h[8:12] == b'WEBP':
-        return 'webp'
-
-tests.append(test_webp)
-
-def test_exr(h, f):
-    """verify is the image ia a OpenEXR fileOpenEXR."""
-    if h.startswith(b'\x76\x2f\x31\x01'):
-        return 'exr'
-
-tests.append(test_exr)
-
-#--------------------#
-# Small test program #
-#--------------------#
-
-def test():
-    import sys
-    recursive = 0
-    if sys.argv[1:] and sys.argv[1] == '-r':
-        del sys.argv[1:2]
-        recursive = 1
-    try:
-        if sys.argv[1:]:
-            testall(sys.argv[1:], recursive, 1)
-        else:
-            testall(['.'], recursive, 1)
-    except KeyboardInterrupt:
-        sys.stderr.write('\n[Interrupted]\n')
-        sys.exit(1)
-
-def testall(list, recursive, toplevel):
-    import sys
-    import os
-    for filename in list:
-        if os.path.isdir(filename):
-            print(filename + '/:', end=' ')
-            if recursive or toplevel:
-                print('recursing down:')
-                import glob
-                names = glob.glob(os.path.join(glob.escape(filename), '*'))
-                testall(names, recursive, 0)
-            else:
-                print('*** directory (use -r) ***')
-        else:
-            print(filename + ':', end=' ')
-            sys.stdout.flush()
-            try:
-                print(what(filename))
-            except OSError:
-                print('*** not found ***')
-
-if __name__ == '__main__':
-    test()
diff --git a/Lib/test/imghdrdata/python-raw.jpg b/Lib/test/imghdrdata/python-raw.jpg
deleted file mode 100644
index 11940b3410ddf..0000000000000
Binary files a/Lib/test/imghdrdata/python-raw.jpg and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.bmp b/Lib/test/imghdrdata/python.bmp
deleted file mode 100644
index 675f95191a45f..0000000000000
Binary files a/Lib/test/imghdrdata/python.bmp and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.exr b/Lib/test/imghdrdata/python.exr
deleted file mode 100644
index 773c81ee1fb85..0000000000000
Binary files a/Lib/test/imghdrdata/python.exr and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.jpg b/Lib/test/imghdrdata/python.jpg
deleted file mode 100644
index 21222c09f5a71..0000000000000
Binary files a/Lib/test/imghdrdata/python.jpg and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.pbm b/Lib/test/imghdrdata/python.pbm
deleted file mode 100644
index 1848ba7ff064e..0000000000000
--- a/Lib/test/imghdrdata/python.pbm
+++ /dev/null
@@ -1,3 +0,0 @@
-P4
-16 16
-ûñ¿úßÕ­±[ñ¥a_ÁX°°ðððð?ÿÿ
\ No newline at end of file
diff --git a/Lib/test/imghdrdata/python.ras b/Lib/test/imghdrdata/python.ras
deleted file mode 100644
index 130e96f817ed9..0000000000000
Binary files a/Lib/test/imghdrdata/python.ras and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.sgi b/Lib/test/imghdrdata/python.sgi
deleted file mode 100644
index ffe9081c7a5b6..0000000000000
Binary files a/Lib/test/imghdrdata/python.sgi and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.tiff b/Lib/test/imghdrdata/python.tiff
deleted file mode 100644
index 39d0bfcec0253..0000000000000
Binary files a/Lib/test/imghdrdata/python.tiff and /dev/null differ
diff --git a/Lib/test/imghdrdata/python.webp b/Lib/test/imghdrdata/python.webp
deleted file mode 100644
index e824ec7fb1c7f..0000000000000
Binary files a/Lib/test/imghdrdata/python.webp and /dev/null differ
diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py
deleted file mode 100644
index 208c8eee455e7..0000000000000
--- a/Lib/test/test_imghdr.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import io
-import os
-import pathlib
-import unittest
-import warnings
-from test.support import findfile, warnings_helper
-from test.support.os_helper import TESTFN, unlink
-
-imghdr = warnings_helper.import_deprecated("imghdr")
-
-
-TEST_FILES = (
-    ('python.png', 'png'),
-    ('python.gif', 'gif'),
-    ('python.bmp', 'bmp'),
-    ('python.ppm', 'ppm'),
-    ('python.pgm', 'pgm'),
-    ('python.pbm', 'pbm'),
-    ('python.jpg', 'jpeg'),
-    ('python-raw.jpg', 'jpeg'),  # raw JPEG without JFIF/EXIF markers
-    ('python.ras', 'rast'),
-    ('python.sgi', 'rgb'),
-    ('python.tiff', 'tiff'),
-    ('python.xbm', 'xbm'),
-    ('python.webp', 'webp'),
-    ('python.exr', 'exr'),
-)
-
-class UnseekableIO(io.FileIO):
-    def tell(self):
-        raise io.UnsupportedOperation
-
-    def seek(self, *args, **kwargs):
-        raise io.UnsupportedOperation
-
-class TestImghdr(unittest.TestCase):
-    @classmethod
-    def setUpClass(cls):
-        cls.testfile = findfile('python.png', subdir='imghdrdata')
-        with open(cls.testfile, 'rb') as stream:
-            cls.testdata = stream.read()
-
-    def tearDown(self):
-        unlink(TESTFN)
-
-    def test_data(self):
-        for filename, expected in TEST_FILES:
-            filename = findfile(filename, subdir='imghdrdata')
-            self.assertEqual(imghdr.what(filename), expected)
-            with open(filename, 'rb') as stream:
-                self.assertEqual(imghdr.what(stream), expected)
-            with open(filename, 'rb') as stream:
-                data = stream.read()
-            self.assertEqual(imghdr.what(None, data), expected)
-            self.assertEqual(imghdr.what(None, bytearray(data)), expected)
-
-    def test_pathlike_filename(self):
-        for filename, expected in TEST_FILES:
-            with self.subTest(filename=filename):
-                filename = findfile(filename, subdir='imghdrdata')
-                self.assertEqual(imghdr.what(pathlib.Path(filename)), expected)
-
-    def test_register_test(self):
-        def test_jumbo(h, file):
-            if h.startswith(b'eggs'):
-                return 'ham'
-        imghdr.tests.append(test_jumbo)
-        self.addCleanup(imghdr.tests.pop)
-        self.assertEqual(imghdr.what(None, b'eggs'), 'ham')
-
-    def test_file_pos(self):
-        with open(TESTFN, 'wb') as stream:
-            stream.write(b'ababagalamaga')
-            pos = stream.tell()
-            stream.write(self.testdata)
-        with open(TESTFN, 'rb') as stream:
-            stream.seek(pos)
-            self.assertEqual(imghdr.what(stream), 'png')
-            self.assertEqual(stream.tell(), pos)
-
-    def test_bad_args(self):
-        with self.assertRaises(TypeError):
-            imghdr.what()
-        with self.assertRaises(AttributeError):
-            imghdr.what(None)
-        with self.assertRaises(TypeError):
-            imghdr.what(self.testfile, 1)
-        with self.assertRaises(AttributeError):
-            imghdr.what(os.fsencode(self.testfile))
-        with open(self.testfile, 'rb') as f:
-            with self.assertRaises(AttributeError):
-                imghdr.what(f.fileno())
-
-    def test_invalid_headers(self):
-        for header in (b'\211PN\r\n',
-                       b'\001\331',
-                       b'\x59\xA6',
-                       b'cutecat',
-                       b'000000JFI',
-                       b'GIF80'):
-            self.assertIsNone(imghdr.what(None, header))
-
-    def test_string_data(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", BytesWarning)
-            for filename, _ in TEST_FILES:
-                filename = findfile(filename, subdir='imghdrdata')
-                with open(filename, 'rb') as stream:
-                    data = stream.read().decode('latin1')
-                with self.assertRaises(TypeError):
-                    imghdr.what(io.StringIO(data))
-                with self.assertRaises(TypeError):
-                    imghdr.what(None, data)
-
-    def test_missing_file(self):
-        with self.assertRaises(FileNotFoundError):
-            imghdr.what('missing')
-
-    def test_closed_file(self):
-        stream = open(self.testfile, 'rb')
-        stream.close()
-        with self.assertRaises(ValueError) as cm:
-            imghdr.what(stream)
-        stream = io.BytesIO(self.testdata)
-        stream.close()
-        with self.assertRaises(ValueError) as cm:
-            imghdr.what(stream)
-
-    def test_unseekable(self):
-        with open(TESTFN, 'wb') as stream:
-            stream.write(self.testdata)
-        with UnseekableIO(TESTFN, 'rb') as stream:
-            with self.assertRaises(io.UnsupportedOperation):
-                imghdr.what(stream)
-
-    def test_output_stream(self):
-        with open(TESTFN, 'wb') as stream:
-            stream.write(self.testdata)
-            stream.seek(0)
-            with self.assertRaises(OSError) as cm:
-                imghdr.what(stream)
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/Lib/test/test_tkinter/test_images.py b/Lib/test/test_tkinter/test_images.py
index b6f8b79ae689f..c07de867ce04b 100644
--- a/Lib/test/test_tkinter/test_images.py
+++ b/Lib/test/test_tkinter/test_images.py
@@ -66,7 +66,7 @@ class BitmapImageTest(AbstractTkTest, unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         AbstractTkTest.setUpClass.__func__(cls)
-        cls.testfile = support.findfile('python.xbm', subdir='imghdrdata')
+        cls.testfile = support.findfile('python.xbm', subdir='tkinterdata')
 
     def test_create_from_file(self):
         image = tkinter.BitmapImage('::img::test', master=self.root,
@@ -150,7 +150,7 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         AbstractTkTest.setUpClass.__func__(cls)
-        cls.testfile = support.findfile('python.gif', subdir='imghdrdata')
+        cls.testfile = support.findfile('python.gif', subdir='tkinterdata')
 
     def create(self):
         return tkinter.PhotoImage('::img::test', master=self.root,
@@ -163,7 +163,7 @@ def colorlist(self, *args):
             return tkinter._join(args)
 
     def check_create_from_file(self, ext):
-        testfile = support.findfile('python.' + ext, subdir='imghdrdata')
+        testfile = support.findfile('python.' + ext, subdir='tkinterdata')
         image = tkinter.PhotoImage('::img::test', master=self.root,
                                    file=testfile)
         self.assertEqual(str(image), '::img::test')
@@ -178,7 +178,7 @@ def check_create_from_file(self, ext):
         self.assertNotIn('::img::test', self.root.image_names())
 
     def check_create_from_data(self, ext):
-        testfile = support.findfile('python.' + ext, subdir='imghdrdata')
+        testfile = support.findfile('python.' + ext, subdir='tkinterdata')
         with open(testfile, 'rb') as f:
             data = f.read()
         image = tkinter.PhotoImage('::img::test', master=self.root,
diff --git a/Lib/test/test_tkinter/widget_tests.py b/Lib/test/test_tkinter/widget_tests.py
index 85b0511aba3c7..f60087a6e9f38 100644
--- a/Lib/test/test_tkinter/widget_tests.py
+++ b/Lib/test/test_tkinter/widget_tests.py
@@ -250,7 +250,7 @@ def test_configure_bitmap(self):
         widget = self.create()
         self.checkParam(widget, 'bitmap', 'questhead')
         self.checkParam(widget, 'bitmap', 'gray50')
-        filename = test.support.findfile('python.xbm', subdir='imghdrdata')
+        filename = test.support.findfile('python.xbm', subdir='tkinterdata')
         self.checkParam(widget, 'bitmap', '@' + filename)
         # Cocoa Tk widgets don't detect invalid -bitmap values
         # See https://core.tcl.tk/tk/info/31cd33dbf0
diff --git a/Lib/test/imghdrdata/python.gif b/Lib/test/tkinterdata/python.gif
similarity index 100%
rename from Lib/test/imghdrdata/python.gif
rename to Lib/test/tkinterdata/python.gif
diff --git a/Lib/test/imghdrdata/python.pgm b/Lib/test/tkinterdata/python.pgm
similarity index 100%
rename from Lib/test/imghdrdata/python.pgm
rename to Lib/test/tkinterdata/python.pgm
diff --git a/Lib/test/imghdrdata/python.png b/Lib/test/tkinterdata/python.png
similarity index 100%
rename from Lib/test/imghdrdata/python.png
rename to Lib/test/tkinterdata/python.png
diff --git a/Lib/test/imghdrdata/python.ppm b/Lib/test/tkinterdata/python.ppm
similarity index 100%
rename from Lib/test/imghdrdata/python.ppm
rename to Lib/test/tkinterdata/python.ppm
diff --git a/Lib/test/imghdrdata/python.xbm b/Lib/test/tkinterdata/python.xbm
similarity index 100%
rename from Lib/test/imghdrdata/python.xbm
rename to Lib/test/tkinterdata/python.xbm
diff --git a/Makefile.pre.in b/Makefile.pre.in
index b277092f20079..7ae94ff02cd28 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2116,7 +2116,6 @@ TESTSUBDIRS=	idlelib/idle_test \
 		test/decimaltestdata \
 		test/dtracedata \
 		test/encoded_modules \
-		test/imghdrdata \
 		test/leakers \
 		test/libregrtest \
 		test/subprocessdata \
@@ -2210,6 +2209,7 @@ TESTSUBDIRS=	idlelib/idle_test \
 		test/test_zipfile \
 		test/test_zoneinfo \
 		test/test_zoneinfo/data \
+		test/tkinterdata \
 		test/tracedmodules \
 		test/typinganndata \
 		test/xmltestdata \
diff --git a/Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst b/Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst
new file mode 100644
index 0000000000000..213b6f5b76425
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst
@@ -0,0 +1,2 @@
+:pep:`594`: Remove the :mod:`!imghdr` module, deprecated in Python 3.11.
+Patch by Victor Stinner.
diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h
index 5af120d254282..925b8b3230fce 100644
--- a/Python/stdlib_module_names.h
+++ b/Python/stdlib_module_names.h
@@ -156,7 +156,6 @@ static const char* _Py_stdlib_module_names[] = {
 "http",
 "idlelib",
 "imaplib",
-"imghdr",
 "importlib",
 "inspect",
 "io",



More information about the Python-checkins mailing list