From e399f46a77263621610b350453e0f50252c6dc08 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 26 May 2023 15:29:45 +0200 Subject: [PATCH] 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. --- Doc/library/imghdr.rst | 86 --------- Doc/library/superseded.rst | 1 - Doc/requirements.txt | 3 +- Doc/whatsnew/3.11.rst | 2 +- Doc/whatsnew/3.12.rst | 2 +- Doc/whatsnew/3.13.rst | 8 + Doc/whatsnew/3.5.rst | 2 +- Lib/imghdr.py | 180 ------------------ Lib/test/imghdrdata/python-raw.jpg | Bin 525 -> 0 bytes Lib/test/imghdrdata/python.bmp | Bin 1162 -> 0 bytes Lib/test/imghdrdata/python.exr | Bin 2635 -> 0 bytes Lib/test/imghdrdata/python.jpg | Bin 543 -> 0 bytes Lib/test/imghdrdata/python.pbm | 3 - Lib/test/imghdrdata/python.ras | Bin 1056 -> 0 bytes Lib/test/imghdrdata/python.sgi | Bin 1967 -> 0 bytes Lib/test/imghdrdata/python.tiff | Bin 1326 -> 0 bytes Lib/test/imghdrdata/python.webp | Bin 432 -> 0 bytes Lib/test/test_imghdr.py | 144 -------------- Lib/test/test_tkinter/test_images.py | 8 +- Lib/test/test_tkinter/widget_tests.py | 2 +- .../{imghdrdata => tkinterdata}/python.gif | Bin .../{imghdrdata => tkinterdata}/python.pgm | Bin .../{imghdrdata => tkinterdata}/python.png | Bin .../{imghdrdata => tkinterdata}/python.ppm | Bin .../{imghdrdata => tkinterdata}/python.xbm | 0 Makefile.pre.in | 2 +- ...-05-23-02-13-11.gh-issue-104773.JNiEjv.rst | 2 + Python/stdlib_module_names.h | 1 - 28 files changed, 21 insertions(+), 425 deletions(-) delete mode 100644 Doc/library/imghdr.rst delete mode 100644 Lib/imghdr.py delete mode 100644 Lib/test/imghdrdata/python-raw.jpg delete mode 100644 Lib/test/imghdrdata/python.bmp delete mode 100644 Lib/test/imghdrdata/python.exr delete mode 100644 Lib/test/imghdrdata/python.jpg delete mode 100644 Lib/test/imghdrdata/python.pbm delete mode 100644 Lib/test/imghdrdata/python.ras delete mode 100644 Lib/test/imghdrdata/python.sgi delete mode 100644 Lib/test/imghdrdata/python.tiff delete mode 100644 Lib/test/imghdrdata/python.webp delete mode 100644 Lib/test/test_imghdr.py rename Lib/test/{imghdrdata => tkinterdata}/python.gif (100%) rename Lib/test/{imghdrdata => tkinterdata}/python.pgm (100%) rename Lib/test/{imghdrdata => tkinterdata}/python.png (100%) rename Lib/test/{imghdrdata => tkinterdata}/python.ppm (100%) rename Lib/test/{imghdrdata => tkinterdata}/python.xbm (100%) create mode 100644 Misc/NEWS.d/next/Library/2023-05-23-02-13-11.gh-issue-104773.JNiEjv.rst diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst deleted file mode 100644 index 630fd7019f94..000000000000 --- 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 24e74110a319..bd17039bc6f6 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 9cbd15c2209d..d3fa6ce6dabc 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 7186ba5521f9..066070eda7db 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 5266f5ffb937..c8fd77f0fdb4 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 0e78a080c430..28c98554fdbf 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 `_, + `puremagic `_, + or `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 cd8f6e2cd9b5..ccf71bf08e86 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 `_ format (contributed by Martin Vignali and Claudiu Popa in :issue:`20295`), and the `WebP `_ format diff --git a/Lib/imghdr.py b/Lib/imghdr.py deleted file mode 100644 index 338688834707..000000000000 --- 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 11940b3410ddf052a996d705006236172e153c25..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 525 zc-s4aGcd3Lg_Q+? zs#%#?5u%Jtg3K(eY>Es*hN5DLjSv6dV&GwB1UiFRkinioWZ9)G>EeUWgoUn5mH8}~ z{6sZ%->#@PnXV2SpDJt$St@_&)Q(@D6jo2Oot`t<^x5q4>(6qRi#IL}m#LR|Rrtu; z^7>U;f;S3hd0~h}7wqbf;6T-e_@6GCvXX?N6?oUY&X-X3A-4QfH!<@CVs50S+QD^?) WroQDtJ+Bmc_f<&Bv#+iHe-i-3ypWUt diff --git a/Lib/test/imghdrdata/python.bmp b/Lib/test/imghdrdata/python.bmp deleted file mode 100644 index 675f95191a45fdb3ae845996d6871b86286f848a..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 1162 zc-noEYe72(!tz6fyd=ClJ?HhT-a+nRzYk~6Iln#UzoRr-RtmVX zAce>}ikrY+AS4aicP?;zxP?-alv83`2u^wE=jC5!caw*Od6t;XL2|QsbyI!4dyL1F zFfh3)lyCU2*16Uo8<7Y^iD(ct5{Yc0{beg|{D(n0u{av?ie-Yv0enXR){iVsi|Pgn zupNzvT%9+~uuS}WfT(GJov#6igOtw;mch0h@kQK`Ra{&G!3w(eB<}rl0H%)soMQ?d z698N29N1UTdu>DfkhSza0Z0t#9sB~|aL7i!TEm~)JGR>F9RdCJ4)5M2L=D6F)aBor zC(mlhkuiRbjeG?(=gL4I>U$t- zZs9I*q@rUVI*dHW4xVGf;4d4Qp}RDJ=`4zewi9xwJ|wo12#^xzFBN0Nn?ciJkm?8rL4=%{{9!6+g8YntIB#&7DQ6R{Z_;+DxhSqFHRM z%Zzk7k9fO!za)!0yezKrvY>Cq%hmZli-CLZjx1VoWB+D>?O^(5m#u+HQ`h5jx_K^( W;&^DsEUq1kVQSMPHT0~IzyA-2^0_7e diff --git a/Lib/test/imghdrdata/python.exr b/Lib/test/imghdrdata/python.exr deleted file mode 100644 index 773c81ee1fb850cdbb6cccd3ae5edabb80146481..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 2635 zc-p;|OK2NM7{|ws9&uwQJ-GIvd6eQfHgzm%ceFb*t0bhgEea`tRK}M!MYSYHph(72 z+!T@$D6)J>DHO-P^Z~_|Pi>*d$t8)QC^D2jE^Z7Z=}ESswDrYtq0si5*^yQ&sqL*Z zEZ=$_-~9GJ{~3AO<7;U}2#sF~CzH`c8eS6dbOyZ)ZD&ynGE0kmUTkOyHnd!5XhGwt z%ac>lbUL0&+TKNHB%BG4#gmcLTjG7#(G-;-PDVof{v}q-V_SY;?J7g># z$y};SfxedC{c5Wjf0S{2pBaCaF>TI3f5`Z*(~JjPX8b_LXWeG}RK^!1&6hG7ZD#zc z&4Rp91ALvP3>4sX)tDnQ{jTSct+?0^bctT3r|2#z5Y$i-1e3#LTc6dt^_K#^&$CHU;5r?q&(KF?u?a_rpuq3?f*#cOwD~3+MT`O= z+= zF2asrysVx8CEW1TayTT%uhgzYg@gN~lQ{b|c91<5&hS$w{YFr5j#2+2d>ukJNrDW4 zGd92(y8cj5aE@-{H}*M0=(v9u7o;;x63G$RF}^nta#r+cLa{kg8UT(0>^0AKjhrJr#Bv6&F5uW>4+V$Q&(+}0SQgIUbwn}O-2o2QKX9xXD|8nR z5%aHQ^$ER4XM{7#!WnadA_RNAr7ZandX3nfkrNctKyjOW3>@p&?u@*kn2=`^A$J|e z3Vk5RGeCY@Tb1J?_*;65zD`fl4@n4D&jyTft4qF!7p9YTvZhby^IC6p*N?LA*nOaQ z2RIfXBgWfYiK^qejh!mTe#v33I7-XdPb;fi+GOx8;f$N0!IqZSy0k0)b@)2B`oNd< z^33hR8PlM_A>+KE8^?^l*iVw;B5*{6Gx!cJSgXs*_oYp8+-E`!|3^*y+QmBY72%8m z-h-21Qeb>SP`Eug;Mfq(7*UQHZy0B66ftl(LRdJ%?fJrJ%>M~+JS92y#2yrIGrunD zIpql4TxC$Br1feu{<5Ih6clbxb^xI1Bw#M0|g3PY{F6NQSQ%5IatS0#4%>Fl-M18Lba<7 zx4+7LQ3NeU2J8EH$$=8{LW|SvZj;}i_l*sCUN#IDv;Xf?%i-t?dh$vSoc0i$$~BLp I5B)FYZ}0KvRR910 diff --git a/Lib/test/imghdrdata/python.jpg b/Lib/test/imghdrdata/python.jpg deleted file mode 100644 index 21222c09f5a71d9d86a0323e49ebc5da6639b22f..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 543 zc-s4aN z4?hnVHy<}AC$AtcAHRTrpa2(-kg$+|Fpw<(GK3MNlbMABs8N8MlUsmf@c#gVAP0j0 zg8(z55(ASUBeNjm|04`yV5cGjb{1BkxQYM+BMT!7(8VxuMkb)kS=l*+gawrtL^utN zfT~2%H8U`<0fm(XfvQ=VSrMX)OoGfTtZa%5LWZJZiH#5c-(uilW&}EeS&+e=L1fvb zEa~Ed&xD1pOqKa8nEXUFb>FV2H<_*u8=op{3RxC}#2pA=S4vz?wZ+4R}$^6SrX zmy0(p4VS5xc~$tx+w%HjrQlCenfI;~dRc5~dg0xvRhTJvR#(ybaiv@y0yEpwOUbgM*7O^DLXw={db;d)fDt@)cR0$^OH?OUFbgEZ%GRs&b)Xw%Qj}a z^XBVSsSz7*1}b*!PuX$#x(y?Y3chU=zZ=W$(@EkZ0<@^X^Yc5NS#h?%feI jL&Kc4v#2uRiBV_%;ikUjK|QY&diPaG%CoPn|9=wzUksC{ diff --git a/Lib/test/imghdrdata/python.pbm b/Lib/test/imghdrdata/python.pbm deleted file mode 100644 index 1848ba7ff064..000000000000 --- 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 130e96f817ed9dd45f411f2f93e0749a4b33ba49..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 1056 zc-n=NZAepL6vuCGQ28Ymf#rIUEFvmPbUJm@ZEh|%X9Q7EAF2PO+6c7+e=g5+p5Hy^f9`!YJJQc{ z95+kUB95C%4{i!KPBd6bT8EQPK7{f3T_oh!BmO`gAG_~zd1Puuz(k-JFc&w2h5m2@ zG`ZKH&c1?ZYZVk}=ax}E;D7wug8MKWxdm;W3+fy@VlpowGQEQF8p_WZgUPp)KB+Mm zKdvCEO+UE_#ik@AHU1b*9bNu+YmlwXK1E017 zLmPn)$-q0U$gUzbgcqI#v3K|BY&Rs&TjXJ;JHLjkfF}d^?9b|mRZ1-2mbd?Go5%XH z#^>01RTljtnbjume7x)qVmA?M@nb_Jmg!*oMOiqVpH2!U#gZbt{9o4frAy`XJPmhx z+Lt>$Ex}GtQy^1rXO&FjyA0f9(hSmUlFZAG)=i+g(NuRe(7lA!)QB}!kQR*dFZ05H z$o3Qaim^-Cbzt*~r@UOOH;puD4Bq^`JI+1QqvVB`p+43v?;q)!o7Y+?ixGRADA+va Si+yUv@2@9Ckrs-1|M&xssHXk^ diff --git a/Lib/test/imghdrdata/python.sgi b/Lib/test/imghdrdata/python.sgi deleted file mode 100644 index ffe9081c7a5b67ed14285041fd0650f4010bc36d..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 1967 zc-rlhZ%kWN7{=ejZ7D4pYMBwG{#oqiV%+9%6v`;{QVJEi&KMVG+=sajlTH*2V8F?= z?S&R_{~J)528J@MB07<&%sDpQKCE#lDjSO<8;P5l``{MSxTHBg_sC_N2$!A@|7$Z!XM zHngBt0E@s=pc700oFTmnNFagC0}C%_wE7MUfW z9()dx$gKby!5-8bK`Cee=&w7E%mbhXd0Qw%Vdbj-zo`x#0=9q7a2F@L%hWCDZs z`xfmx3)}`QV1Y)KHg*GHo;LrZRwjF%{qqp8n4J1yGI63u6{U{li>-HB6w%>JBso95WtBxq1ygzs zl(KVYPyaZ{PpZOSUi9!{o~wvpQqQHN%W7nL{QKz0z}1?$*|XDAlL=L?O0~Bvb*55O>_SAr$+g% zB1J07U3R*fGH{lX>w~S$&(itdepQ>Wld^YUcyJfJuo+Ft3YXbfF1!dfI_@7#B9>&8 z)LvETF16?CD0CquaE!M{g0H+3SfL~7*qP}mc1pIsIPk%Hdpxi_V&PJDKa=0h=-7In zw^DpAiBtu>zWULMvXWH=_WV5hUFoyEtL?QdP4$}tH5=%=nV;E|>>WP%aeQEJcWifr zJY@xJDZC6k#IZF|WSkUv%;)up&LY7s2&jf6bbo9^~X{(XQ+{yrj==im==m! zp^h{cW?31fnUB&xvXaa+BSVEAETIQ+Nf^I==j?7>vOMFv`#b0SKIiv1cZ-a4V{EOM zc_XH*r!DHtgIUF?I}n!N3c<&kA@Il*);FoD61NwlESUv{s7#l@QAdL; zuT?9_Y-kpzR_T1y=XHLm)s*FU1;ZTm z4e%D@Qq~<=7ce|^X35#Iyc=Vtnnj+J2TPj9GLjC@wm_TwK}_J6CAUsw!`Y;5cD!|afd#V!pBu3*2Z0q` zBcX&mA4kq6=dR%F0@O;*pKOSD{#((upm_=yslb}rLOeeRZ5yujZ?3;!-+ywvVIx31aG>o}HPbNpsIkR;!uc*;LyH diff --git a/Lib/test/imghdrdata/python.webp b/Lib/test/imghdrdata/python.webp deleted file mode 100644 index e824ec7fb1c7fa85716d27454e9d1715a896d4b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 432 zc-jH50Z;x?Nk&Gf0RRA3MM6+kP&il$0000G0000F000jF06|PpNW%aC00AeWsF5V) zdgmBl=ie%sh?xI$agE?6Fyi5hcQVMq5nO{SFzB#&6^?jOHNglB0#A~lYOqxq9M-mN zMlVjrc09K2cl)m?t|6lTNzwg}koUSoNhBLOC6P4q6m1U2)8!T*^a~Wekl};38Zw?X zf`1(;eol4>`-q;ik?)yvM(8qv+xW~#viC(WeIWfd7mOh?RxPF0Ya_f}@)trH( z*>09~iWo5uimEJ7H2N@t-@0p1QYp19&*@YY3IPBB09H^qAie+q0FVLzodGHk01yBJ z05m1A0(3A>2!#xM104t~{pbMx{dA!H0-GO-_d|S~H}=vDuhaiEXyWdty~%GI^s2>U zuDYL>gx^7;JK9_1@A%8{y?^1a`ak6f?DV^4U;nBp*?-Aw=Z5C2m$~G|^phiuU)_&6 zRUm(rPy9Lf|8LT31L&W;gP3M*vDFj*b{FQc{#}aXpGUv5`oI1i9rF^8{#?(&`uP~c az0c1dkvX6N{h9$wF)ZG^*?X$20000=+R1SM diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py deleted file mode 100644 index 208c8eee455e..000000000000 --- 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 b6f8b79ae689..c07de867ce04 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 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase): 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 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase): 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 85b0511aba3c..f60087a6e9f3 100644 --- a/Lib/test/test_tkinter/widget_tests.py +++ b/Lib/test/test_tkinter/widget_tests.py @@ -250,7 +250,7 @@ class StandardOptionsTests: 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 b277092f2007..7ae94ff02cd2 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 000000000000..213b6f5b7642 --- /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 5af120d25428..925b8b3230fc 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", -- 2.47.3