From be49e674707e09e1a2422e38d41206eee4af6a3e Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 9 Apr 2022 20:04:39 -0700 Subject: [PATCH 01/12] Deprecate imghdr --- Doc/includes/email-mime.py | 5 +---- Doc/library/email.mime.rst | 14 +++++++++----- Lib/email/mime/image.py | 13 ++++++------- Lib/imghdr.py | 5 +++++ Lib/test/test_email/test_email.py | 8 ++++---- Lib/test/test_imghdr.py | 5 +++-- 6 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py index 6af2be0b08a48d..e22eb079fa86a9 100644 --- a/Doc/includes/email-mime.py +++ b/Doc/includes/email-mime.py @@ -1,9 +1,6 @@ # Import smtplib for the actual sending function import smtplib -# And imghdr to find the types of our images -import imghdr - # Here are the email package modules we'll need from email.message import EmailMessage @@ -22,7 +19,7 @@ with open(file, 'rb') as fp: img_data = fp.read() msg.add_attachment(img_data, maintype='image', - subtype=imghdr.what(None, img_data)) + subtype="jpeg") # Send the email via our own SMTP server. with smtplib.SMTP('localhost') as s: diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index f37f6aa28dec7d..67896f99524b6a 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -180,11 +180,11 @@ Here are the classes: A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the :class:`MIMEImage` class is used to create MIME message objects of major type :mimetype:`image`. *_imagedata* is a string containing the raw image data. If - this data can be decoded by the standard Python module :mod:`imghdr`, then the - subtype will be automatically included in the :mailheader:`Content-Type` header. - Otherwise you can explicitly specify the image subtype via the *_subtype* - argument. If the minor type could not be guessed and *_subtype* was not given, - then :exc:`TypeError` is raised. + this data can be decoded by the standard Python module :mod:`imghdr` + (which is deprecated), then the subtype will be automatically included in the + :mailheader:`Content-Type` header. Otherwise you can explicitly specify the + image subtype via the *_subtype* argument. If the minor type could not be + guessed and *_subtype* was not given, then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, @@ -204,6 +204,10 @@ Here are the classes: .. versionchanged:: 3.6 Added *policy* keyword-only parameter. + .. versionchanged:: 3.11 + Deprecated the default value for *_subtype* due :mod:`imghdr` being + deprecated. + .. currentmodule:: email.mime.message .. class:: MIMEMessage(_msg, _subtype='rfc822', *, policy=compat32) diff --git a/Lib/email/mime/image.py b/Lib/email/mime/image.py index 92724643cdeeac..b0bb471d11a2dd 100644 --- a/Lib/email/mime/image.py +++ b/Lib/email/mime/image.py @@ -6,13 +6,11 @@ __all__ = ['MIMEImage'] -import imghdr - from email import encoders from email.mime.nonmultipart import MIMENonMultipart - + class MIMEImage(MIMENonMultipart): """Class for generating image/* type MIME documents.""" @@ -21,10 +19,10 @@ def __init__(self, _imagedata, _subtype=None, """Create an image/* type MIME document. _imagedata is a string containing the raw image data. If this data - can be decoded by the standard Python `imghdr' module, then the - subtype will be automatically included in the Content-Type header. - Otherwise, you can specify the specific image subtype via the _subtype - parameter. + can be decoded by the standard Python `imghdr' module + (which is deprecated), then the subtype will be automatically included + in the Content-Type header. Otherwise, you can specify the specific + image subtype via the _subtype parameter. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this @@ -38,6 +36,7 @@ def __init__(self, _imagedata, _subtype=None, header. """ if _subtype is None: + import imghdr _subtype = imghdr.what(None, _imagedata) if _subtype is None: raise TypeError('Could not guess image MIME subtype') diff --git a/Lib/imghdr.py b/Lib/imghdr.py index afcb67772ee9a9..6a372e66c7f261 100644 --- a/Lib/imghdr.py +++ b/Lib/imghdr.py @@ -1,9 +1,14 @@ """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 # #-------------------------# diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index ca9c773bbc559a..58ead0b52de7cb 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -799,7 +799,7 @@ class TestEncoders(unittest.TestCase): def test_EncodersEncode_base64(self): with openfile('PyBanner048.gif', 'rb') as fp: bindata = fp.read() - mimed = email.mime.image.MIMEImage(bindata) + mimed = email.mime.image.MIMEImage(bindata, 'gif') base64ed = mimed.get_payload() # the transfer-encoded body lines should all be <=76 characters lines = base64ed.split('\n') @@ -1557,7 +1557,7 @@ class TestMIMEImage(unittest.TestCase): def setUp(self): with openfile('PyBanner048.gif', 'rb') as fp: self._imgdata = fp.read() - self._im = MIMEImage(self._imgdata) + self._im = MIMEImage(self._imgdata, _subtype='gif') def test_guess_minor_type(self): self.assertEqual(self._im.get_content_type(), 'image/gif') @@ -1750,7 +1750,7 @@ def setUp(self): with openfile('PyBanner048.gif', 'rb') as fp: data = fp.read() container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') - image = MIMEImage(data, name='dingusfish.gif') + image = MIMEImage(data, name='dingusfish.gif', _subtype="gif") image.add_header('content-disposition', 'attachment', filename='dingusfish.gif') intro = MIMEText('''\ @@ -3449,7 +3449,7 @@ def test_mime_classes_policy_argument(self): classes = [ (MIMEApplication, ('',)), (MIMEAudio, (audiodata,)), - (MIMEImage, (bindata,)), + (MIMEImage, (bindata, 'gif')), (MIMEMessage, (Message(),)), (MIMENonMultipart, ('multipart', 'mixed')), (MIMEText, ('',)), diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py index ca0a0b23c3cf1a..208c8eee455e7b 100644 --- a/Lib/test/test_imghdr.py +++ b/Lib/test/test_imghdr.py @@ -1,12 +1,13 @@ -import imghdr import io import os import pathlib import unittest import warnings -from test.support import findfile +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'), From 32dc8f4574a2ef16b18ff81ce07ec442ba299c33 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 10 Apr 2022 10:57:47 -0700 Subject: [PATCH 02/12] Make the email.mime.MIMEImage deprecation more explicit --- Doc/library/email.mime.rst | 4 ++-- Lib/email/mime/image.py | 12 +++++++++++- Lib/test/test_email/test_email.py | 7 +++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index 67896f99524b6a..d6366f8f6a710c 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -204,8 +204,8 @@ Here are the classes: .. versionchanged:: 3.6 Added *policy* keyword-only parameter. - .. versionchanged:: 3.11 - Deprecated the default value for *_subtype* due :mod:`imghdr` being + .. deprecated:: 3.11 + The default argument for *_subtype* due :mod:`imghdr` being deprecated. .. currentmodule:: email.mime.message diff --git a/Lib/email/mime/image.py b/Lib/email/mime/image.py index b0bb471d11a2dd..44eff6864a5afb 100644 --- a/Lib/email/mime/image.py +++ b/Lib/email/mime/image.py @@ -8,6 +8,11 @@ from email import encoders from email.mime.nonmultipart import MIMENonMultipart +import warnings + +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + import imghdr @@ -36,7 +41,12 @@ def __init__(self, _imagedata, _subtype=None, header. """ if _subtype is None: - import imghdr + fullname = f"{__name__}.{self.__class__.__qualname__}" + msg = ("The *_subtype* argument's default value for {name}" + "is deprecated due to the deprecation of imghdr (slated for " + "removal in Python {remove}); explicitly specify the image " + "subtype") + warnings._deprecated(fullname, msg, remove=(3, 13)) _subtype = imghdr.what(None, _imagedata) if _subtype is None: raise TypeError('Could not guess image MIME subtype') diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 58ead0b52de7cb..7684b9dfbf2dd9 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -7,6 +7,7 @@ import base64 import unittest import textwrap +import warnings from io import StringIO, BytesIO from itertools import chain @@ -1590,6 +1591,12 @@ def test_add_header(self): self.assertIs(self._im.get_param('attachment', missing, header='foobar'), missing) + def test_subtype_default_deprecation(self): + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + with self.assertRaises(DeprecationWarning): + self._im = MIMEImage(self._imgdata) + # Test the basic MIMEApplication class From 05bcb051270bfe623dbfbfa9668e09d2ab8e93eb Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 10 Apr 2022 11:00:01 -0700 Subject: [PATCH 03/12] Add a What's New entry for `_subtype` --- Doc/whatsnew/3.11.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 870330c57969a6..abc5328da2f4be 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -846,6 +846,10 @@ Deprecated (Contributed by Brett Cannon in :issue:`47061`.) +* The default argument for *_subtype* for :cls:`email.mime.MIMEImage` + has been deprecated due to the deprecation of :mod:`imghdr`. Please + explicitly provide a an image subtype. + Removed ======= From 5dd70d530f381d04083cc82685778b3568083d20 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 11 Apr 2022 17:03:02 -0700 Subject: [PATCH 04/12] Add a What's new entry --- Doc/whatsnew/3.11.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 0f15308a56a2ce..26b50ba017d4e8 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -852,6 +852,7 @@ Deprecated * :mod:`cgitb` * :mod:`chunk` * :mod:`crypt` + * :mod:`imghdr` (Contributed by Brett Cannon in :issue:`47061`.) From a296bf8d6261b0e4e9c55a7f06e86116002685b2 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 11 Apr 2022 17:05:03 -0700 Subject: [PATCH 05/12] Add a news entry --- .../next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst diff --git a/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst b/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst new file mode 100644 index 00000000000000..89dc196b621603 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst @@ -0,0 +1,2 @@ +Deprecate the imghdr module. Along the way, deprecate the default argument +for email.mime.MIMEImage's *_subtype* parameter. From 670d268f1025ecdc3b477aea63503c927e017ed5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 11 Apr 2022 17:22:40 -0700 Subject: [PATCH 06/12] Fix a Sphinx directive mistake --- Doc/whatsnew/3.11.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 26b50ba017d4e8..3dcc690833b27f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -856,7 +856,7 @@ Deprecated (Contributed by Brett Cannon in :issue:`47061`.) -* The default argument for *_subtype* for :cls:`email.mime.MIMEImage` +* The default argument for *_subtype* for :class:`email.mime.MIMEImage` has been deprecated due to the deprecation of :mod:`imghdr`. Please explicitly provide a an image subtype. From 1cd90575eac786eca862b7aa467b81d1c71fbf3f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 12 Apr 2022 12:09:33 -0700 Subject: [PATCH 07/12] Update Doc/library/email.mime.rst Co-authored-by: Hugo van Kemenade --- Doc/library/email.mime.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index d6366f8f6a710c..7cf9a2336a9a3a 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -205,7 +205,7 @@ Here are the classes: Added *policy* keyword-only parameter. .. deprecated:: 3.11 - The default argument for *_subtype* due :mod:`imghdr` being + The default argument for *_subtype* due to :mod:`imghdr` being deprecated. .. currentmodule:: email.mime.message From 59857627bc4cdd09565584ad93b8cda93a2174af Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 12 Apr 2022 12:10:52 -0700 Subject: [PATCH 08/12] Update Doc/whatsnew/3.11.rst Co-authored-by: Hugo van Kemenade --- Doc/whatsnew/3.11.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 3dcc690833b27f..0bc054d8ef3fda 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -860,6 +860,7 @@ Deprecated has been deprecated due to the deprecation of :mod:`imghdr`. Please explicitly provide a an image subtype. +(Contributed by Brett Cannon in :issue:`47061`.) Removed ======= From 71a9acaf4c8278e3090969022794c961123b6130 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 12 Apr 2022 12:11:14 -0700 Subject: [PATCH 09/12] Update 3.11.rst --- Doc/whatsnew/3.11.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 0bc054d8ef3fda..468d9e4cfeea1c 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -858,7 +858,7 @@ Deprecated * The default argument for *_subtype* for :class:`email.mime.MIMEImage` has been deprecated due to the deprecation of :mod:`imghdr`. Please - explicitly provide a an image subtype. + explicitly provide an image subtype. (Contributed by Brett Cannon in :issue:`47061`.) From 450e383a4acc095b620b62bf2b47b5b4e98a67c3 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 12 Apr 2022 15:08:16 -0700 Subject: [PATCH 10/12] Update email-mime.py Single quotes for consistency. --- Doc/includes/email-mime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py index e22eb079fa86a9..c87db6a064b006 100644 --- a/Doc/includes/email-mime.py +++ b/Doc/includes/email-mime.py @@ -19,7 +19,7 @@ with open(file, 'rb') as fp: img_data = fp.read() msg.add_attachment(img_data, maintype='image', - subtype="jpeg") + subtype='jpeg') # Send the email via our own SMTP server. with smtplib.SMTP('localhost') as s: From edb29aa39d79557da7e80de046dc0e9cc40ec884 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 12 Apr 2022 19:28:41 -0700 Subject: [PATCH 11/12] Inline `imghdr` into `email.mime.image` --- Doc/library/email.mime.rst | 15 +-- Doc/whatsnew/3.11.rst | 4 - Lib/email/mime/image.py | 125 +++++++++++++++--- Lib/test/test_email/test_email.py | 15 +-- ...2-04-11-17-04-38.gh-issue-91217.QVDLOq.rst | 3 +- 5 files changed, 119 insertions(+), 43 deletions(-) diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index d6366f8f6a710c..ab4f7bc54e0256 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -180,11 +180,12 @@ Here are the classes: A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the :class:`MIMEImage` class is used to create MIME message objects of major type :mimetype:`image`. *_imagedata* is a string containing the raw image data. If - this data can be decoded by the standard Python module :mod:`imghdr` - (which is deprecated), then the subtype will be automatically included in the - :mailheader:`Content-Type` header. Otherwise you can explicitly specify the - image subtype via the *_subtype* argument. If the minor type could not be - guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + this data type can be detected (jpeg, png, gif, tiff, rgb, pbm, pgm, ppm, + rast, xbm, bmp, webp, and exr attempted), then the subtype will be + automatically included in the :mailheader:`Content-Type` header. Otherwise + you can explicitly specify the image subtype via the *_subtype* argument. + If the minor type could not be guessed and *_subtype* was not given, then + :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, @@ -204,10 +205,6 @@ Here are the classes: .. versionchanged:: 3.6 Added *policy* keyword-only parameter. - .. deprecated:: 3.11 - The default argument for *_subtype* due :mod:`imghdr` being - deprecated. - .. currentmodule:: email.mime.message .. class:: MIMEMessage(_msg, _subtype='rfc822', *, policy=compat32) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 3dcc690833b27f..7b79be42cb2f38 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -856,10 +856,6 @@ Deprecated (Contributed by Brett Cannon in :issue:`47061`.) -* The default argument for *_subtype* for :class:`email.mime.MIMEImage` - has been deprecated due to the deprecation of :mod:`imghdr`. Please - explicitly provide a an image subtype. - Removed ======= diff --git a/Lib/email/mime/image.py b/Lib/email/mime/image.py index 44eff6864a5afb..877b0e2d891062 100644 --- a/Lib/email/mime/image.py +++ b/Lib/email/mime/image.py @@ -10,10 +10,108 @@ from email.mime.nonmultipart import MIMENonMultipart import warnings -with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - import imghdr +# Originally from the imghdr module. +def _what(h): + for tf in tests: + if res := tf(h): + return res + else: + return None + +tests = [] + +def _test_jpeg(h): + """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): + if h.startswith(b'\211PNG\r\n\032\n'): + return 'png' + +tests.append(_test_png) + +def _test_gif(h): + """GIF ('87 and '89 variants)""" + if h[:6] in (b'GIF87a', b'GIF89a'): + return 'gif' + +tests.append(_test_gif) + +def _test_tiff(h): + """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): + """SGI image library""" + if h.startswith(b'\001\332'): + return 'rgb' + +tests.append(_test_rgb) + +def _test_pbm(h): + """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): + """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): + """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): + """Sun raster file""" + if h.startswith(b'\x59\xA6\x6A\x95'): + return 'rast' + +tests.append(_test_rast) + +def _test_xbm(h): + """X bitmap (X10 or X11)""" + if h.startswith(b'#define '): + return 'xbm' + +tests.append(_test_xbm) + +def _test_bmp(h): + if h.startswith(b'BM'): + return 'bmp' + +tests.append(_test_bmp) + +def _test_webp(h): + if h.startswith(b'RIFF') and h[8:12] == b'WEBP': + return 'webp' + +tests.append(_test_webp) + +def _test_exr(h): + if h.startswith(b'\x76\x2f\x31\x01'): + return 'exr' + +tests.append(_test_exr) class MIMEImage(MIMENonMultipart): @@ -23,11 +121,11 @@ def __init__(self, _imagedata, _subtype=None, _encoder=encoders.encode_base64, *, policy=None, **_params): """Create an image/* type MIME document. - _imagedata is a string containing the raw image data. If this data - can be decoded by the standard Python `imghdr' module - (which is deprecated), then the subtype will be automatically included - in the Content-Type header. Otherwise, you can specify the specific - image subtype via the _subtype parameter. + _imagedata is a string containing the raw image data. If the data + type can be detected (jpeg, png, gif, tiff, rgb, pbm, pgm, ppm, + rast, xbm, bmp, webp, and exr attempted), then the subtype will be + automatically included in the Content-Type header. Otherwise, you can + specify the specific image subtype via the _subtype parameter. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this @@ -41,15 +139,8 @@ def __init__(self, _imagedata, _subtype=None, header. """ if _subtype is None: - fullname = f"{__name__}.{self.__class__.__qualname__}" - msg = ("The *_subtype* argument's default value for {name}" - "is deprecated due to the deprecation of imghdr (slated for " - "removal in Python {remove}); explicitly specify the image " - "subtype") - warnings._deprecated(fullname, msg, remove=(3, 13)) - _subtype = imghdr.what(None, _imagedata) - if _subtype is None: - raise TypeError('Could not guess image MIME subtype') + if (_subtype := _what(_imagedata)) is None: + raise TypeError('Could not guess image MIME subtype') MIMENonMultipart.__init__(self, 'image', _subtype, policy=policy, **_params) self.set_payload(_imagedata) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 7684b9dfbf2dd9..b87dae22de1d22 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -800,7 +800,7 @@ class TestEncoders(unittest.TestCase): def test_EncodersEncode_base64(self): with openfile('PyBanner048.gif', 'rb') as fp: bindata = fp.read() - mimed = email.mime.image.MIMEImage(bindata, 'gif') + mimed = email.mime.image.MIMEImage(bindata) base64ed = mimed.get_payload() # the transfer-encoded body lines should all be <=76 characters lines = base64ed.split('\n') @@ -1558,7 +1558,7 @@ class TestMIMEImage(unittest.TestCase): def setUp(self): with openfile('PyBanner048.gif', 'rb') as fp: self._imgdata = fp.read() - self._im = MIMEImage(self._imgdata, _subtype='gif') + self._im = MIMEImage(self._imgdata) def test_guess_minor_type(self): self.assertEqual(self._im.get_content_type(), 'image/gif') @@ -1591,13 +1591,6 @@ def test_add_header(self): self.assertIs(self._im.get_param('attachment', missing, header='foobar'), missing) - def test_subtype_default_deprecation(self): - with warnings.catch_warnings(): - warnings.simplefilter("error", DeprecationWarning) - with self.assertRaises(DeprecationWarning): - self._im = MIMEImage(self._imgdata) - - # Test the basic MIMEApplication class class TestMIMEApplication(unittest.TestCase): @@ -1757,7 +1750,7 @@ def setUp(self): with openfile('PyBanner048.gif', 'rb') as fp: data = fp.read() container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') - image = MIMEImage(data, name='dingusfish.gif', _subtype="gif") + image = MIMEImage(data, name='dingusfish.gif') image.add_header('content-disposition', 'attachment', filename='dingusfish.gif') intro = MIMEText('''\ @@ -3456,7 +3449,7 @@ def test_mime_classes_policy_argument(self): classes = [ (MIMEApplication, ('',)), (MIMEAudio, (audiodata,)), - (MIMEImage, (bindata, 'gif')), + (MIMEImage, (bindata,)), (MIMEMessage, (Message(),)), (MIMENonMultipart, ('multipart', 'mixed')), (MIMEText, ('',)), diff --git a/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst b/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst index 89dc196b621603..3e59c205aae293 100644 --- a/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst +++ b/Misc/NEWS.d/next/Library/2022-04-11-17-04-38.gh-issue-91217.QVDLOq.rst @@ -1,2 +1 @@ -Deprecate the imghdr module. Along the way, deprecate the default argument -for email.mime.MIMEImage's *_subtype* parameter. +Deprecate the imghdr module. From aa85754251b87df94e1f275370cd90a747f4f876 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 12 Apr 2022 21:17:11 -0700 Subject: [PATCH 12/12] Update image.py Remove unnecessary `warnings` import. --- Lib/email/mime/image.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/email/mime/image.py b/Lib/email/mime/image.py index 877b0e2d891062..fac238c7289fa8 100644 --- a/Lib/email/mime/image.py +++ b/Lib/email/mime/image.py @@ -8,7 +8,6 @@ from email import encoders from email.mime.nonmultipart import MIMENonMultipart -import warnings # Originally from the imghdr module.