Specifically, the Message object’s get_payload method we used earlier accepts an op-
tional decode argument to control automatic email-style MIME decoding (e.g., Base64,
uuencode, quoted-printable). If this argument is passed in as 1 (or equivalently, True),
the payload’s data is MIME-decoded when fetched, if required. Because this argument
is so useful for complex messages with arbitrary parts, it will normally be passed as true
in all cases. Binary parts are normally MIME-encoded, but even text parts might also
be present in Base64 or another MIME form if their bytes fall outside email standards.
Some types of Unicode text, for example, require MIME encoding.
The upshot is that get_payload normally returns str strings for str text parts, but re-
turns bytes strings if its decode argument is true—even if the message part is known to
be text by nature. If this argument is not used, the payload’s type depends upon how
it was set: str or bytes. Because Python 3.X does not allow str and bytes to be mixed
freely, clients that need to use the result in text processing or store it in files need to
accommodate the difference. Let’s run some code to illustrate:
>>> from email.message import Message
>>> m = Message()
>>> m['From'] = 'Lancelot'
>>> m.set_payload('Line?...')
>>> m['From']
'Lancelot'
>>> m.get_payload() # str, if payload is str
'Line?...'
>>> m.get_payload(decode=1) # bytes, if MIME decode (same as decode=True)
b'Line?...'
The combination of these different return types and Python 3.X’s strict str/bytes di-
chotomy can cause problems in code that processes the result unless they decode
carefully:
>>> m.get_payload(decode=True) + 'spam' # can't mix in 3.X!
TypeError: can't concat bytes to str
>>> m.get_payload(decode=True).decode() + 'spam' # convert if required
'Line?...spam'
To make sense of these examples, it may help to remember that there are two different
concepts of “encoding” for email text:
- Email-style MIME encodings such as Base64, uuencode, and quoted-printable,
which are applied to binary and otherwise unusual content to make them accept-
able for transmission in email text - Unicode text encodings for strings in general, which apply to message text as well
as its parts, and may be required after MIME encoding for text message parts
The email package handles email-style MIME encodings automatically when we pass
decode=1 to fetch parsed payloads, or generate text for messages that have nonprintable
parts, but scripts still need to take Unicode encodings into consideration because of
930 | Chapter 13: Client-Side Scripting