Skip to content

Commit 3995ef9

Browse files
stevenbucciniamcgregor
authored andcommitted
In Python 2.7, encode strings in add_header() as ASCII (#72)
* In Python 2, encode other strings in add_header() calls into ASCII so getting this filename does not cause Unicode errors * Fix test compatibility in Python3
1 parent aa415c3 commit 3995ef9

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

marrow/mailer/message.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,18 @@ def attach(self, name, data=None, maintype=None, subtype=None,
322322
filename=(filename_charset, filename_language, filename)
323323

324324
if inline:
325-
part.add_header('Content-Disposition', 'inline', filename=filename)
326-
part.add_header('Content-ID', '<%s>' % filename)
325+
if sys.version_info < (3, 0):
326+
part.add_header('Content-Disposition'.encode('utf-8'), 'inline'.encode('utf-8'), filename=filename)
327+
part.add_header('Content-ID'.encode('utf-8'), '<%s>'.encode('utf-8') % filename)
328+
else:
329+
part.add_header('Content-Disposition', 'inline', filename=filename)
330+
part.add_header('Content-ID', '<%s>' % filename)
327331
self.embedded.append(part)
328332
else:
329-
part.add_header('Content-Disposition', 'attachment', filename=filename)
333+
if sys.version_info < (3, 0):
334+
part.add_header('Content-Disposition'.encode('utf-8'), 'attachment'.encode('utf-8'), filename=filename)
335+
else:
336+
part.add_header('Content-Disposition', 'attachment', filename=filename)
330337
self.attachments.append(part)
331338

332339
def embed(self, name, data=None):

test/test_message.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,29 @@ def test_mime_embed_failures(self):
281281

282282
with pytest.raises(TypeError):
283283
message.embed('test.gif', object())
284+
285+
def test_that_add_header_and_collapse_header_are_inverses_ascii_filename(self):
286+
message = self.build_message()
287+
message.plain = "Hello world."
288+
message.rich = "Farewell cruel world."
289+
message.attach("wat.txt", b"not a unicode snowman") # calls add_header() under the covers
290+
attachment = message.attachments[0]
291+
filename = attachment.get_filename() # calls email.utils.collapse_rfc2231_value() under the covers
292+
assert filename == "wat.txt"
293+
294+
def test_that_add_header_and_collapse_header_are_inverses_non_ascii_filename(self):
295+
message = self.build_message()
296+
message.plain = "Hello world."
297+
message.rich = "Farewell cruel world."
298+
message.attach("☃.txt", b"unicode snowman", filename_language='en-us')
299+
attachment = message.attachments[0]
300+
filename = attachment.get_param('filename', object(), 'content-disposition') # get_filename() calls this under the covers
301+
assert isinstance(filename, tuple) # Since attachment encoded according to RFC2231, should be represented as a tuple
302+
filename = attachment.get_filename() # Calls email.utils.collapse_rfc2231_value() under the covers, currently fails
303+
if sys.version_info < (3, 0):
304+
assert isinstance(filename, basestring) # Successfully converts tuple to a string
305+
else:
306+
assert isinstance(filename, str)
284307

285308
def test_recipients_collection(self):
286309
message = self.build_message()

0 commit comments

Comments
 (0)