Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8a97896

Browse files
committed
#21091: make is_attachment a method.
Since EmailMessage is a provisional API we can fix API bugs in a maintenance release, but I used a trick suggested by Serhiy to maintain backward compatibility with 3.4.0/1.
1 parent 97dfad7 commit 8a97896

4 files changed

Lines changed: 43 additions & 10 deletions

File tree

Doc/library/email.contentmanager.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,15 @@ this module.
7070
the following methods:
7171

7272

73-
.. attribute:: is_attachment
73+
.. method:: is_attachment
7474

75-
Set to ``True`` if there is a :mailheader:`Content-Disposition` header
75+
Return ``True`` if there is a :mailheader:`Content-Disposition` header
7676
and its (case insensitive) value is ``attachment``, ``False`` otherwise.
7777

78+
.. versionchanged:: 3.4.2
79+
is_attachment is now a method instead of a property, for consistency
80+
with :meth:`~email.message.Message.is_multipart`.
81+
7882

7983
.. method:: get_body(preferencelist=('related', 'html', 'plain'))
8084

Lib/email/message.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import re
1010
import uu
1111
import quopri
12+
import warnings
1213
from io import BytesIO, StringIO
1314

1415
# Intrapackage imports
@@ -929,6 +930,17 @@ def get_charsets(self, failobj=None):
929930
# I.e. def walk(self): ...
930931
from email.iterators import walk
931932

933+
# XXX Support for temporary deprecation hack for is_attachment property.
934+
class _IsAttachment:
935+
def __init__(self, value):
936+
self.value = value
937+
def __call__(self):
938+
return self.value
939+
def __bool__(self):
940+
warnings.warn("is_attachment will be a method, not a property, in 3.5",
941+
DeprecationWarning,
942+
stacklevel=3)
943+
return self.value
932944

933945
class MIMEPart(Message):
934946

@@ -941,10 +953,12 @@ def __init__(self, policy=None):
941953
@property
942954
def is_attachment(self):
943955
c_d = self.get('content-disposition')
944-
return False if c_d is None else c_d.content_disposition == 'attachment'
956+
result = False if c_d is None else c_d.content_disposition == 'attachment'
957+
# XXX transitional hack to raise deprecation if not called.
958+
return _IsAttachment(result)
945959

946960
def _find_body(self, part, preferencelist):
947-
if part.is_attachment:
961+
if part.is_attachment():
948962
return
949963
maintype, subtype = part.get_content_type().split('/')
950964
if maintype == 'text':
@@ -1037,7 +1051,7 @@ def iter_attachments(self):
10371051
for part in parts:
10381052
maintype, subtype = part.get_content_type().split('/')
10391053
if ((maintype, subtype) in self._body_types and
1040-
not part.is_attachment and subtype not in seen):
1054+
not part.is_attachment() and subtype not in seen):
10411055
seen.append(subtype)
10421056
continue
10431057
yield part

Lib/test/test_email/test_message.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -722,15 +722,25 @@ def message_as_clear_content(self, body_parts, attachments, parts, msg):
722722

723723
def test_is_attachment(self):
724724
m = self._make_message()
725-
self.assertFalse(m.is_attachment)
725+
self.assertFalse(m.is_attachment())
726+
with self.assertWarns(DeprecationWarning):
727+
self.assertFalse(m.is_attachment)
726728
m['Content-Disposition'] = 'inline'
727-
self.assertFalse(m.is_attachment)
729+
self.assertFalse(m.is_attachment())
730+
with self.assertWarns(DeprecationWarning):
731+
self.assertFalse(m.is_attachment)
728732
m.replace_header('Content-Disposition', 'attachment')
729-
self.assertTrue(m.is_attachment)
733+
self.assertTrue(m.is_attachment())
734+
with self.assertWarns(DeprecationWarning):
735+
self.assertTrue(m.is_attachment)
730736
m.replace_header('Content-Disposition', 'AtTachMent')
731-
self.assertTrue(m.is_attachment)
737+
self.assertTrue(m.is_attachment())
738+
with self.assertWarns(DeprecationWarning):
739+
self.assertTrue(m.is_attachment)
732740
m.set_param('filename', 'abc.png', 'Content-Disposition')
733-
self.assertTrue(m.is_attachment)
741+
self.assertTrue(m.is_attachment())
742+
with self.assertWarns(DeprecationWarning):
743+
self.assertTrue(m.is_attachment)
734744

735745

736746
class TestEmailMessage(TestEmailMessageBase, TestEmailBase):

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ Core and Builtins
3232
Library
3333
-------
3434

35+
- Issue #21091: Fix API bug: email.message.EmailMessage.is_attachment is now
36+
a method. Since EmailMessage is provisional, we can change the API in a
37+
maintenance release, but we use a trick to remain backward compatible with
38+
3.4.0/1.
39+
3540
- Issue #21079: Fix email.message.EmailMessage.is_attachment to return the
3641
correct result when the header has parameters as well as a value.
3742

0 commit comments

Comments
 (0)