Skip to main content

Lib/email/message.py (part 4)

Source:

cpython 3.14 @ ab2d84fe1023/Lib/email/message.py

This annotation covers the Message object API. See modules_email3_detail for parsing, header decoding, and MIME types.

Map

LinesSymbolRole
1-80Message.__setitem__Add or replace a header
81-160Message.get_payloadGet the message body or sub-parts
161-240Message.set_payloadSet the message body
241-320Message.get_content_typeParse Content-Type header
321-500Message.walkDepth-first traversal of MIME parts

Reading

Message.__setitem__

# CPython: Lib/email/message.py:380 Message.__setitem__
def __setitem__(self, name, val):
# Headers are stored as a list of (name, value) pairs
# Multiple headers with the same name are allowed (e.g., Received:)
max_count = self.policy.header_max_count(name)
if max_count:
if len(self) + 1 > max_count:
del self[name] # remove existing if at limit
self._headers.append(
self.policy.header_store_parse(name, val))

Headers are stored as an ordered list, not a dict. This preserves ordering and allows multiple values for the same header name. policy.header_max_count enforces RFC limits (e.g., Subject should appear at most once).

Message.get_payload

# CPython: Lib/email/message.py:460 Message.get_payload
def get_payload(self, i=None, decode=False):
if self.is_multipart():
if decode:
return None
if i is None:
return self._payload # list of sub-messages
return self._payload[i]
# Non-multipart
if decode:
# Decode Content-Transfer-Encoding
cte = str(self.get('content-transfer-encoding', '')).lower()
if cte == 'quoted-printable':
return quopri.decodestring(self._payload.encode())
elif cte == 'base64':
return base64.decodebytes(self._payload.encode())
return self._payload

decode=True applies Content-Transfer-Encoding decoding (base64 or quoted-printable). For multipart messages, i selects a specific part by index.

Message.walk

# CPython: Lib/email/message.py:620 Message.walk
def walk(self):
yield self
if self.is_multipart():
for subpart in self.get_payload():
yield from subpart.walk()

walk() yields each Message object in the tree depth-first. Useful for processing all attachments:

for part in msg.walk():
if part.get_content_maintype() == 'multipart': continue
filename = part.get_filename()

gopy notes

Message.__setitem__ is module/email.MessageSetItem in module/email/module.go. Headers are stored as a []HeaderPair slice. get_payload returns the body string or sub-messages slice. walk is a recursive iterator over the MIME tree.