email.message: Представление электронного сообщения
Исходный код: Lib/email/message.py
Введено в версии 3.6: 1
Центральным классом в пакете email является класс EmailMessage, импортируемый из модуля email.message. Он является базовым классом для модели объектов email. EmailMessage предоставляет основные функции для установки и запроса полей заголовка, доступа к телам сообщений и создания или изменения структурированных сообщений.
Электронное сообщение состоит из заголовков и полезной нагрузки (также называемой содержимым). Заголовки являются именами и значениями полей в стиле RFC 5322 или RFC 6532, где имя и значение поля разделены двоеточием. Двоеточие не является частью ни имени, ни значения поля. Полезная нагрузка может быть простым текстовым сообщением, двоичным объектом или структурированной последовательностью подсообщений, каждое со своим набором заголовков и собственной полезной нагрузкой. Последний тип полезной нагрузки указывается типом MIME сообщения, таким как multipart/* или message/rfc822.
Концептуальная модель, предоставляемая объектом EmailMessage, представляет собой упорядоченный словарь заголовков, связанных с полезной нагрузкой, которая представляет собой тело сообщения RFC 5322, которое может быть списком под-EmailMessage объектов. В дополнение к обычным методам словаря для доступа к именам и значениям заголовков существуют методы для доступа к специализированной информации из заголовков (например, типу контента MIME), для работы с полезной нагрузкой, для генерации сериализованной версии сообщения и для рекурсивного обхода дерева объектов.
Интерфейс EmailMessage типа словарь индексируется именами заголовков, которые должны быть ASCII-значениями. Значения словаря — строки с дополнительными методами. Заголовки хранятся и возвращаются в формате с сохранением регистра, но имена полей сравниваются без учёта регистра. В отличие от реального словаря, ключи упорядочены, и ключи могут повторяться. Предоставляются дополнительные методы для работы с заголовками, имеющими повторяющиеся ключи.
Полезная нагрузка — это строка или байтовый объект в случае простых объектов сообщений или список объектов EmailMessage в случае документов контейнеров MIME, таких как multipart/* и message/rfc822 объектов сообщений.
-
class email.message.EmailMessage(policy=default) -
Если указана policy, используйте правила, которые она задаёт, для обновления и сериализации представления сообщения. Если policy не задана, используйте политику
default, которая следует правилам RFC для электронной почты, за исключением символов конца строки (вместо предписанных RFC\r\n, она использует стандартные Python-шные\nсимволы конца строки). Для получения дополнительной информации см. документациюpolicy.-
as_string(unixfrom=False, maxheaderlen=None, policy=None) -
Возвращает всё сообщение, выровненное в строку. При опциональном unixfrom = true, заголовок конверта включён в возвращаемую строку. unixfrom по умолчанию равно
False. Для обратной совместимости с базовым классомMessageпринимается maxheaderlen, но по умолчанию равноNone, что означает, что длина строки по умолчанию контролируетсяmax_line_lengthполитики. Аргумент policy может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может использоваться для управления некоторыми форматами, создаваемыми методом, так как указанная policy будет переданаGenerator.Выравнивание сообщения может вызвать изменения в
EmailMessage, если по умолчанию необходимо заполнить данные для завершения преобразования в строку (например, могут быть сгенерированы или изменены границы MIME).Обратите внимание, что этот метод предоставляется для удобства и может не быть самым полезным способом сериализации сообщений в вашем приложении, особенно если вы работаете с несколькими сообщениями. См.
email.generator.Generatorдля более гибкого API сериализации сообщений. Также обратите внимание, что этот метод ограничен созданием сериализованных сообщений в «чистом» 7-битном формате, когдаutf8равноFalse, что является значением по умолчанию.Изменено в версии 3.6: поведение по умолчанию, когда maxheaderlen не указан, было изменено с по умолчанию 0 на по умолчанию max_line_length из политики.
-
__str__() -
Эквивалентно
as_string(policy=self.policy.clone(utf8=True)). Позволяетstr(msg)генерировать строку, содержащую сериализованное сообщение в удобочитаемом формате.Изменено в версии 3.4: метод был изменён на использование
utf8=True, тем самым создавая представление сообщения в стиле RFC 6531, вместо непосредственного алиаса дляas_string().
-
as_bytes(unixfrom=False, policy=None) -
Возвращает всё сообщение, выровненное в байтовую строку. При опциональном unixfrom = true, заголовок конверта включён в возвращаемую строку. unixfrom по умолчанию равно
False. Аргумент policy может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может использоваться для управления некоторыми форматами, создаваемыми методом, так как указанная policy будет переданаBytesGenerator.Выравнивание сообщения может вызвать изменения в
EmailMessage, если по умолчанию необходимо заполнить данные для завершения преобразования в строку (например, могут быть сгенерированы или изменены границы MIME).Обратите внимание, что этот метод предоставляется для удобства и может не быть самым полезным способом сериализации сообщений в вашем приложении, особенно если вы работаете с несколькими сообщениями. См.
email.generator.BytesGeneratorдля более гибкого API сериализации сообщений.
-
__bytes__() -
Эквивалентно
as_bytes(). Позволяетbytes(msg)генерировать байтовую строку, содержащую сериализованное сообщение.
-
is_multipart() -
Возвращает
Trueесли содержимое сообщения является списком под-EmailMessageобъектов, в противном случае возвращаетFalse. Когдаis_multipart()возвращаетFalse, содержимое должно быть строковым объектом (который может быть кодированным CTE двоичным содержимым). Обратите внимание, чтоis_multipart(), возвращающийTrue, не обязательно означает, что «msg.get_content_maintype() == ‘multipart’” вернётTrue. Например,is_multipartвернётTrueкогдаEmailMessageимеет типmessage/rfc822.
-
set_unixfrom(unixfrom) -
Устанавливает заголовок конверта сообщения в unixfrom, который должен быть строкой. (См.
mboxMessageдля краткого описания этого заголовка.)
-
get_unixfrom() -
Возвращает заголовок конверта сообщения. По умолчанию
None, если заголовок конверта никогда не устанавливался.
Следующие методы реализуют интерфейс отображения для доступа к заголовкам сообщения. Обратите внимание, что между этими методами и обычным интерфейсом отображения (например, словаря) существуют некоторые семантические различия. Например, в словаре нет дублирующих ключей, но здесь могут быть дублирующиеся заголовки сообщений. Также в словарях нет гарантированного порядка ключей, возвращаемых
keys(), но в объектеEmailMessageзаголовки всегда возвращаются в порядке их появления в исходном сообщении или в порядке их добавления в сообщение позднее. Любой удалённый и затем повторно добавленный заголовок всегда добавляется в конец списка заголовков.Эти семантические различия намеренные и призваны обеспечить удобство в наиболее распространённых случаях использования.
Обратите внимание, что во всех случаях заголовок конверта, присутствующий в сообщении, не включён в интерфейс отображения.
-
__len__() -
Возвращает общее количество заголовков, включая дубликаты.
-
__contains__(name) -
Возвращает true, если объект сообщения имеет поле с именем name. Сопоставление выполняется без учёта регистра, и name не включает заключительный двоеточие. Используется для оператора
in. Например:if 'message-id' in myMessage: print('Message-ID:', myMessage['message-id'])
-
__getitem__(name) -
Возвращает значение поля заголовка с заданным именем. name не включает разделитель двоеточие. Если заголовок отсутствует, возвращается
None;KeyErrorникогда не генерируется.Обратите внимание, что если заданное поле появляется более одного раза в заголовках сообщения, то какой из этих значений поля будет возвращён, не определено. Используйте метод
get_all()для получения значений всех существующих заголовков с именем name.Используя стандартные (не-
compat32) политики, возвращаемое значение является экземпляром подклассаemail.headerregistry.BaseHeader.
-
__setitem__(name, val) -
Добавляет заголовок в сообщение с именем поля name и значением val. Поле добавляется в конец существующих заголовков сообщения.
Обратите внимание, что это не перезаписывает или удаляет любой существующий заголовок с тем же именем. Если вы хотите убедиться, что новый заголовок является единственным в сообщении с именем поля name, сначала удалите поле, например:
del msg['subject'] msg['subject'] = 'Python roolz!'
Если
policyопределяет уникальность некоторых заголовков (как делают стандартные политики), этот метод может генерироватьValueErrorпри попытке присвоить значение такому заголовку, когда он уже существует. Это поведение намеренное для обеспечения согласованности, но не полагайтесь на него, так как в будущем мы можем выбрать автоматическое удаление существующего заголовка при таких операциях.
-
__delitem__(name) -
Удаляет все вхождения поля с именем name из заголовков сообщения. Исключение не генерируется, если заданное поле не присутствует в заголовках.
-
keys() -
Возвращает список всех имён полей заголовков сообщения.
-
-
values() -
Возвращает список всех значений полей сообщения.
-
items() -
Возвращает список пар кортежей (2-кортежи), содержащих заголовки и значения всех полей сообщения.
-
get(name, failobj=None) -
Возвращает значение поля заголовка с указанным именем. Это идентично
__getitem__(), за исключением того, что если указанного заголовка нет, возвращается необязательный параметр failobj (по умолчаниюNone).
Вот несколько дополнительных полезных методов, связанных с заголовками:
-
get_all(name, failobj=None) -
Возвращает список всех значений для поля с именем name. Если в сообщении нет заголовков с указанным именем, возвращается failobj (по умолчанию
None).
-
add_header(_name, _value, **_params) -
Расширенная установка заголовка. Этот метод похож на
__setitem__(), но позволяет передавать дополнительные параметры в качестве именованных аргументов. _name — добавляемое поле заголовка, а _value — его основное значение.Для каждого элемента в словаре аргументов _params ключ используется в качестве имени параметра, при этом подчеркивания заменяются дефисами (так как дефисы недопустимы в именах переменных Python). Обычно параметр будет добавлен как
key="value", если значение неNone, в противном случае будет добавлен только ключ.Если значение содержит не-ASCII символы, наборы символов и языки могут быть явно заданы, задав значение в виде кортежа из трёх элементов в формате
(CHARSET, LANGUAGE, VALUE), гдеCHARSET— строка, обозначающая наборы символов для кодирования значения,LANGUAGEобычно может быть установлено вNoneили пустую строку (см. RFC 2231 для других возможностей), иVALUE— строка со значениями не-ASCII кодов. Если кортеж из трёх элементов не передан, а значение содержит не-ASCII символы, оно автоматически кодируется в формате RFC 2231 с использованиемCHARSETutf-8иLANGUAGENone.Вот пример:
msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')Это добавит заголовок, который будет выглядеть так
Content-Disposition: attachment; filename="bud.gif"
Пример расширенного интерфейса с не-ASCII символами:
msg.add_header('Content-Disposition', 'attachment', filename=('iso-8859-1', '', 'Fußballer.ppt'))
-
replace_header(_name, _value) -
Заменяет заголовок. Заменяет первый найденный в сообщении заголовок, соответствующий _name, сохраняя порядок заголовков и регистр имени поля исходного заголовка. Если соответствующий заголовок не найден, возбуждается исключение
KeyError.
-
get_content_type() -
Возвращает тип контента сообщения, приведённый к нижнему регистру в формате maintype/subtype. Если в сообщении нет заголовка Content-Type, возвращается значение, возвращаемое
get_default_type(). Если заголовок Content-Type некорректен, возвращаетсяtext/plain.(Согласно RFC 2045, у сообщений всегда есть тип по умолчанию,
get_content_type()всегда возвращает значение. RFC 2045 определяет тип сообщения по умолчанию как text/plain, за исключением случаев, когда оно находится внутри контейнера multipart/digest, в котором случае он будет message/rfc822. Если в заголовке Content-Type указан некорректный тип, RFC 2045 предписывает, что тип по умолчанию должен быть text/plain.)
-
get_content_maintype() -
Возвращает основной тип контента сообщения. Это часть maintype строки, возвращаемой
get_content_type().
-
get_content_subtype() -
Возвращает подтип контента сообщения. Это часть subtype строки, возвращаемой
get_content_type().
-
get_default_type() -
Возвращает тип контента по умолчанию. Большинство сообщений имеют тип контента по умолчанию text/plain, за исключением сообщений, являющихся подчастями контейнеров multipart/digest. Такие подчасти имеют тип контента по умолчанию message/rfc822.
-
set_default_type(ctype) -
Устанавливает тип контента по умолчанию. ctype должен быть либо text/plain, либо message/rfc822, хотя это и не проверяется. Тип контента по умолчанию не хранится в заголовке Content-Type, поэтому он влияет только на возвращаемое значение методов
get_content_typeпри отсутствии заголовка Content-Type в сообщении.
-
set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False) -
Устанавливает параметр в заголовке Content-Type. Если параметр уже существует в заголовке, заменяет его значение на value. Когда header равно
Content-Type(по умолчанию) и заголовок ещё не существует в сообщении, добавляет его, устанавливает его значение в text/plain и добавляет новое значение параметра. Необязательный параметр header определяет альтернативный заголовок к Content-Type.Если значение содержит не-ASCII символы, набор символов и язык могут быть явно заданы с помощью необязательных параметров charset и language. Необязательный параметр language указывает язык RFC 2231, по умолчанию пустую строку. И charset, и language должны быть строками. По умолчанию используется
utf8charset иNoneдля language.Если replace равно
False(по умолчанию), заголовок перемещается в конец списка заголовков. Если replace равноTrue, заголовок будет обновлён на месте.Использование параметра requote с объектами
EmailMessageустарело.Обратите внимание, что значения существующих параметров заголовков можно получить через атрибут
paramsзначения заголовка (например,msg['Content-Type'].params['charset']).Изменено в версии 3.4:
replaceключевое слово было добавлено.
-
del_param(param, header='content-type', requote=True) -
Полностью удаляет указанный параметр из заголовка Content-Type. Заголовок будет переписан на месте без параметра и его значения. Необязательный параметр header указывает альтернативу Content-Type.
Использование параметра requote с объектами
EmailMessageустарело.
-
get_filename(failobj=None) -
Возвращает значение параметра
filenameзаголовка Content-Disposition сообщения. Если заголовок не имеет параметраfilename, этот метод переходит к поиску параметраnameв заголовке Content-Type. Если ни тот, ни другой параметр не найден, или заголовок отсутствует, возвращается failobj. Возвращаемая строка всегда будет без кавычек, как и вemail.utils.unquote().
-
get_boundary(failobj=None) -
Возвращает значение параметра
boundaryзаголовка Content-Type сообщения, или failobj, если заголовок отсутствует или не имеет параметраboundary. Возвращаемая строка всегда будет без кавычек, как и вemail.utils.unquote().
-
-
set_boundary(boundary) -
Установите параметр
boundaryзаголовка Content-Type на boundary.set_boundary()всегда будет заключать boundary в кавычки при необходимости. Если у объекта сообщения нет заголовка Content-Type, генерируетсяHeaderParseError.Обратите внимание, что использование этого метода отличается от удаления старого заголовка Content-Type и добавления нового с новым значением boundary с помощью
add_header(), так какset_boundary()сохраняет порядок заголовка Content-Type в списке заголовков.
-
get_content_charset(failobj=None) -
Возвращает параметр
charsetзаголовка Content-Type, приведённый к нижнему регистру. Если заголовка Content-Type нет или у него нет параметраcharset, возвращается failobj.
-
get_charsets(failobj=None) -
Возвращает список имён наборов символов в сообщении. Если сообщение является multipart, список будет содержать по одному элементу для каждого подраздела в содержимом, в противном случае это будет список длины 1.
Каждый элемент списка будет строкой, представляющей значение параметра
charsetв заголовке Content-Type для соответствующего подраздела. Если у подраздёла нет заголовка Content-Type, нет параметраcharsetили основного MIME-типа не text, то этот элемент в возвращаемом списке будет failobj.
-
is_attachment() -
Возвращает
True, если есть заголовок Content-Disposition и его значение (без учёта регистра) равноattachment, иначеFalse.Изменено в версии 3.4.2: is_attachment теперь является методом, а не свойством, для согласованности с
is_multipart().
-
get_content_disposition() -
Возвращает значение заголовка Content-Disposition сообщения в нижнем регистре (без параметров), если он есть, или
None. Возможные значения для этого метода: inline, attachment илиNone, если сообщение соответствует RFC 2183.Добавлена в версии 3.5.
Следующие методы связаны с запросом и изменением содержимого (payload) сообщения.
-
walk() -
Метод
walk()— универсальный генератор, который можно использовать для итерации по всем частям и подчастям дерева объекта сообщения в порядке обхода в глубину. Обычно вы используетеwalk()в качестве итератора в циклеfor; на каждой итерации возвращается следующая подчасть.Вот пример, который выводит MIME-тип каждой части структуры multipart-сообщения:
>>> for part in msg.walk(): ... print(part.get_content_type()) multipart/report text/plain message/delivery-status text/plain text/plain message/rfc822 text/plain
walkитерируется по подчастям любой части, гдеis_multipart()возвращаетTrue, даже еслиmsg.get_content_maintype() == 'multipart'может возвращатьFalse. Мы можем увидеть это в нашем примере, воспользовавшись функцией отладки_structure:>>> for part in msg.walk(): ... print(part.get_content_maintype() == 'multipart', ... part.is_multipart()) True True False False False True False False False False False True False False >>> _structure(msg) multipart/report text/plain message/delivery-status text/plain text/plain message/rfc822 text/plainЗдесь части
messageне являютсяmultiparts, но они содержат подчасти.is_multipart()возвращаетTrueиwalkспускается в подчасти.
-
get_body(preferencelist=('related', 'html', 'plain')) -
Возвращает MIME-часть, которая является лучшим кандидатом на роль «тела» сообщения.
preferencelist должен быть последовательностью строк из набора
related,html, иplain, и указывает порядок предпочтения типа содержимого возвращаемой части.Начните поиск соответствий с объекта, на котором вызван метод
get_body.Если
relatedне включено в preferencelist, рассматривайте корневую часть (или подчасть корневой части) любых связанных частей в качестве кандидата, если (под-)часть соответствует предпочтению.При обнаружении
multipart/related, проверьте параметрstart, и если найдена часть с совпадающим заголовком Content-ID, рассматривайте только её при поиске подходящих кандидатов. В противном случае рассматривайте только первую (по умолчанию корневую) частьmultipart/related.Если ни одна из частей не соответствует ни одному из предпочтений в preferencelist, возвращается
None.Примечания: (1) Для большинства приложений единственные осмысленные комбинации preferencelist —
('plain',),('html', 'plain'), и по умолчанию('related', 'html', 'plain'). (2) Поскольку соответствие начинается с объекта, на котором вызванget_body, вызовget_bodyнаmultipart/relatedвернёт сам объект, если preferencelist не имеет значения по умолчанию. (3) Сообщения (или части сообщений), которые не задают заголовок Content-Type или у которых заголовок Content-Type некорректен, будут обрабатываться так, как будто они имеют типtext/plain, что иногда может привести к тому, чтоget_bodyвернёт неожиданные результаты.
-
iter_attachments() -
Возвращает итератор по всем непосредственным подчастям сообщения, которые не являются частями «тела» кандидата. То есть пропустите первое вхождение каждого из
text/plain,text/html,multipart/related, илиmultipart/alternative(если они не отмечены явно как вложения с помощью Content-Disposition: attachment) и верните все оставшиеся части. При применении непосредственно кmultipart/related, возвращает итератор по всем связанным частям, кроме корневой части (т. е. части, указанной параметромstart, или первой части, если нет параметраstartили параметрstartне соответствует Content-ID какой-либо из частей). При применении непосредственно кmultipart/alternativeили не-multipart, возвращает пустой итератор.
-
iter_parts() -
Возвращает итератор по всем непосредственным подчастям сообщения, который будет пустым для не-
multipart. (См. такжеwalk().)
-
get_content(*args, content_manager=None, **kw) -
Вызывает метод
get_content()объекта content_manager, передавая self в качестве объекта сообщения и передавая любые другие аргументы или ключевые слова как дополнительные аргументы. Если content_manager не указан, используйтеcontent_manager, указанный текущимpolicy.
-
set_content(*args, content_manager=None, **kw) -
Вызывает метод
set_content()объекта content_manager, передавая self в качестве объекта сообщения и передавая любые другие аргументы или ключевые слова как дополнительные аргументы. Если content_manager не указан, используйтеcontent_manager, указанный текущимpolicy.
-
Преобразует сообщение, которое не является
multipart, в сообщениеmultipart/related, перемещая все существующие заголовки Content- и содержимое в первую (новую) частьmultipart. Если указан boundary, используйте его как строку раздела в multipart, в противном случае оставьте раздел для автоматического создания при необходимости (например, при сериализации сообщения).
-
make_alternative(boundary=None) -
Преобразует сообщение, которое не является
multipartилиmultipart/related, вmultipart/alternative, перемещая все существующие заголовки Content- и содержимое в первую (новую) частьmultipart. Если указан boundary, используйте его как строку раздела в multipart, в противном случае оставьте раздел для автоматического создания при необходимости (например, при сериализации сообщения).
-
-
make_mixed(boundary=None) -
Преобразуйте не-
multipart,multipart/related, илиmultipart-alternativeвmultipart/mixed, перемещая все существующие заголовки Content- и содержимое в первую (новую) частьmultipart. Если указан boundary, используйте его в качестве разделителя в составном сообщении, иначе оставьте разделитель, чтобы он был создан автоматически при необходимости (например, при сериализации сообщения).
-
Если сообщение является
multipart/related, создайте новый объект сообщения, передайте все аргументы в его методset_content()иattach()его вmultipart. Если сообщение — не-multipart, вызовитеmake_related(), а затем продолжите как выше. Если сообщение — любого другого типаmultipart, вызовитеTypeError. Если content_manager не указан, используйтеcontent_manager, указанный текущимpolicy. Если добавленная часть не имеет заголовка Content-Disposition, добавьте его со значениемinline.
-
add_alternative(*args, content_manager=None, **kw) -
Если сообщение является
multipart/alternative, создайте новый объект сообщения, передайте все аргументы в его методset_content()иattach()его вmultipart. Если сообщение — не-multipartилиmultipart/related, вызовитеmake_alternative(), а затем продолжите как выше. Если сообщение — любого другого типаmultipart, вызовитеTypeError. Если content_manager не указан, используйтеcontent_manager, указанный текущимpolicy.
-
add_attachment(*args, content_manager=None, **kw) -
Если сообщение является
multipart/mixed, создайте новый объект сообщения, передайте все аргументы в его методset_content()иattach()его вmultipart. Если сообщение — не-multipart,multipart/related, илиmultipart/alternative, вызовитеmake_mixed(), а затем продолжите как выше. Если content_manager не указан, используйтеcontent_manager, указанный текущимpolicy. Если добавленная часть не имеет заголовка Content-Disposition, добавьте его со значениемattachment. Этот метод может использоваться как для явных вложений (Content-Disposition: attachment), так и для вложений по умолчанию (Content-Disposition: inline), передав соответствующие параметры вcontent_manager.
-
clear() -
Удалить содержимое и все заголовки.
-
clear_content() -
Удалить содержимое и все заголовки
Content-, сохранив все остальные заголовки в исходном порядке.
EmailMessageобъекты имеют следующие атрибуты экземпляров:-
preamble -
Формат MIME-документа допускает некоторый текст между пустой строкой после заголовков и первой строкой разделителя составного сообщения. Обычно этот текст не виден в почтовом клиенте, поддерживающем MIME, так как он находится за пределами стандартной MIME-защиты. Однако при просмотре исходного текста сообщения или при просмотре сообщения в почтовом клиенте, не поддерживающем MIME, этот текст может стать видимым.
Атрибут preamble содержит этот вводный текст вне зоны защиты для MIME-документов. Когда
Parserобнаруживает некоторый текст после заголовков, но перед первой строкой разделителя, он присваивает этот текст атрибуту preamble сообщения. КогдаGeneratorзаписывает обычный текстовый вид MIME-сообщения и обнаруживает, что у сообщения есть атрибут preamble, он запишет этот текст в область между заголовками и первым разделителем. Подробности см. вemail.parserиemail.generator.Обратите внимание, что если у объекта сообщения нет преамбулы, атрибут preamble будет
None.
-
epilogue -
Атрибут epilogue ведет себя так же, как атрибут preamble, за исключением того, что он содержит текст, который появляется между последним разделителем и концом сообщения. Как и с
preamble, если текст эпилога отсутствует, этот атрибут будетNone.
-
defects -
Атрибут defects содержит список всех проблем, обнаруженных при разборе этого сообщения. Подробное описание возможных проблем при разборе см. в
email.errors.
-
-
class email.message.MIMEPart(policy=default) -
Этот класс представляет собой часть MIME-сообщения. Он идентичен
EmailMessage, за исключением того, что заголовки MIME-Version не добавляются при вызовеset_content(), так как составным частям не нужны собственные заголовки MIME-Version.
Примечания
-
1 -
Изначально добавлен в 3.4 в качестве пробного модуля. Документация для устаревшего класса сообщений перемещена в email.message.Message: Представление электронного сообщения с использованием API compat32.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/email.message.html