Spec-Zone.ru › Python 3.11

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. Значения словаря — строки с дополнительными методами. Заголовки хранятся и возвращаются с сохранением регистра, но названия полей сопоставляются без учёта регистра. Ключи упорядочены, однако, в отличие от обычного словаря, могут повторяться. Для работы с заголовками, имеющими повторяющиеся ключи, предусмотрены дополнительные методы.

Полезная нагрузка — это либо строковый объект или объект bytes для простых сообщений, либо список объектов EmailMessage для MIME-контейнеров, например сообщений multipart/* и message/rfc822.

class email.message.EmailMessage(policy=default)

Если указана policy, используйте заданные ею правила для обновления и сериализации представления сообщения. Если policy не задана, используйте политику default, которая следует правилам RFC для электронной почты, за исключением окончаний строк (вместо предписанных RFC \r\n используются окончания строк \n, принятые в стандартной библиотеке Python). Дополнительные сведения см. в документации по policy.

as_string(unixfrom=False, maxheaderlen=None, policy=None)

Возвращает всё сообщение в виде строки. Если необязательный параметр unixfrom имеет значение true, в возвращаемую строку включается заголовок конверта. По умолчанию unixfrom равен False. Для обратной совместимости с базовым классом Message принимается параметр maxheaderlen, значение которого по умолчанию — None; это означает, что по умолчанию длина строки определяется параметром max_line_length политики. Аргумент policy можно использовать для переопределения политики по умолчанию, полученной из экземпляра сообщения. С его помощью можно управлять некоторыми аспектами форматирования, выполняемого методом, поскольку указанная policy будет передана в Generator.

Преобразование сообщения в строку может изменить EmailMessage, если для завершения преобразования в строку необходимо заполнить значения по умолчанию (например, границы MIME могут быть созданы или изменены).

Обратите внимание, что этот метод предоставлен для удобства и может быть не самым полезным способом сериализации сообщений в приложении, особенно если вы работаете с несколькими сообщениями. Более гибкий API для сериализации сообщений см. в документации по email.generator.Generator. Также обратите внимание, что этот метод может создавать сообщения только в формате «7 bit clean», если 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)

Возвращает всё сообщение в виде объекта bytes. Если необязательный параметр unixfrom имеет значение true, в возвращаемую строку включается заголовок конверта. По умолчанию unixfrom равен False. Аргумент policy можно использовать для переопределения политики по умолчанию, полученной из экземпляра сообщения. С его помощью можно управлять некоторыми аспектами форматирования, выполняемого методом, поскольку указанная policy будет передана в BytesGenerator.

Преобразование сообщения в строку может изменить EmailMessage, если для завершения преобразования в строку необходимо заполнить значения по умолчанию (например, границы MIME могут быть созданы или изменены).

Обратите внимание, что этот метод предоставлен для удобства и может быть не самым полезным способом сериализации сообщений в приложении, особенно если вы работаете с несколькими сообщениями. Более гибкий API для сериализации сообщений см. в документации по email.generator.BytesGenerator.

__bytes__()

Эквивалентно as_bytes(). Позволяет bytes(msg) создать объект bytes с сериализованным сообщением.

is_multipart()

Возвращает True, если полезная нагрузка сообщения представляет собой список объектов-подсообщений EmailMessage; в противном случае возвращает False. Если is_multipart() возвращает False, полезная нагрузка должна быть строковым объектом (который может содержать двоичные данные, закодированные CTE). Обратите внимание, что возврат True методом is_multipart() не обязательно означает, что «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 никогда не возбуждается.

Обратите внимание: если указанное поле встречается в заголовках сообщения несколько раз, не определено, какое именно из этих значений будет возвращено. Чтобы получить значения всех существующих заголовков с именем name, используйте метод get_all().

При использовании стандартных политик (не 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()

Возвращает список пар из двух элементов, содержащих все поля заголовков сообщения и их значения.

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 с использованием CHARSET, равного utf-8, и LANGUAGE, равного None.

Пример:

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()

Возвращает тип содержимого сообщения в нижнем регистре в формате основной_тип/подтип. Если в сообщении отсутствует заголовок 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()

Возвращает основной тип содержимого сообщения. Это часть основной_тип строки, возвращаемой методом get_content_type().

get_content_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 должны быть строками. По умолчанию для charset используется utf8, а для language — None.

Если 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. Заголовок перезаписывается на прежнем месте без параметра и его значения. Необязательный параметр headerContent-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 и добавления нового с новой границей с помощью 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.

Следующие методы предназначены для проверки и изменения содержимого (полезной нагрузки) сообщения.

walk()

Метод walk() — универсальный генератор, который можно использовать для обхода всех частей и вложенных частей дерева объектов сообщения в порядке обхода в глубину. Обычно walk() используется как итератор в цикле for; на каждой итерации возвращается следующая вложенная часть.

Ниже приведён пример, который выводит MIME-тип каждой части структуры составного сообщения:

>>> 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:

>>> from email.iterators import _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.

Если у части есть заголовок Content-Disposition, считайте её подходящим кандидатом, только если значение заголовка равно inline.

Если ни один кандидат не соответствует ни одному из предпочтений в 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.

make_related(boundary=None)

Преобразовать сообщение, не являющееся multipart, в сообщение multipart/related, переместив все существующие заголовки Content- и содержимое в новую первую часть multipart. Если задан параметр boundary, использовать его в качестве строки-разделителя составного сообщения; в противном случае оставить её автоматическое создание на момент необходимости (например, при сериализации сообщения).

make_alternative(boundary=None)

Преобразовать сообщение, не являющееся multipart, или сообщение multipart/related в multipart/alternative, переместив все существующие заголовки Content- и содержимое в новую первую часть multipart. Если задан параметр boundary, использовать его в качестве строки-разделителя составного сообщения; в противном случае оставить её автоматическое создание на момент необходимости (например, при сериализации сообщения).

make_mixed(boundary=None)

Преобразовать сообщение, не являющееся multipart, сообщение multipart/related или сообщение multipart-alternative в multipart/mixed, переместив все существующие заголовки Content- и содержимое в новую первую часть multipart. Если задан параметр boundary, использовать его в качестве строки-разделителя составного сообщения; в противном случае оставить её автоматическое создание на момент необходимости (например, при сериализации сообщения).

add_related(*args, content_manager=None, **kw)

Если сообщение является 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), так и для вложений inline (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, за исключением того, что при вызове set_content() заголовки MIME-Version не добавляются, поскольку подчастям не нужны собственные заголовки MIME-Version.

Сноски

[1]

Впервые добавлен в версии 3.4 как предварительный модуль. Документация по устаревшему классу сообщений перенесена в раздел email.message.Message: представление сообщения электронной почты с помощью API compat32.

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/email.message.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API