Spec-Zone.ru › Python 3.13

email.headerregistry: Пользовательские объекты заголовков

Исходный код: Lib/email/headerregistry.py

Добавлено в версии 3.6: [1]

Заголовки представлены специализированными подклассами str. Конкретный класс, используемый для представления заданного заголовка, определяется значением header_factory объекта policy, действующего при создании заголовков. В этом разделе описан конкретный header_factory, реализованный пакетом email для обработки сообщений электронной почты, соответствующих RFC 5322. Он не только предоставляет специализированные объекты заголовков для различных типов заголовков, но и механизм расширения, позволяющий приложениям добавлять собственные типы заголовков.

При использовании любых объектов политики, производных от EmailPolicy, все заголовки создаются с помощью HeaderRegistry, а их последним базовым классом является BaseHeader. У каждого класса заголовка есть дополнительный базовый класс, определяемый типом заголовка. Например, многие заголовки имеют в качестве другого базового класса UnstructuredHeader. Специализированный второй класс заголовка определяется его именем с помощью таблицы поиска, хранящейся в HeaderRegistry. Для типичных прикладных программ всё это происходит прозрачно, однако для более сложных приложений предусмотрены интерфейсы, позволяющие изменять поведение по умолчанию.

В разделах ниже сначала описаны базовые классы заголовков и их атрибуты, затем API для изменения поведения HeaderRegistry и, наконец, вспомогательные классы, используемые для представления данных, разобранных из структурированных заголовков.

class email.headerregistry.BaseHeader(name, value)

name и value передаются в BaseHeader из вызова header_factory. Строковое значение любого объекта заголовка — это value, полностью декодированное в Юникод.

Этот базовый класс определяет следующие свойства только для чтения:

name

Имя заголовка (часть поля перед «:»). Это в точности значение, переданное в вызове header_factory для name; то есть регистр сохраняется.

defects

Кортеж экземпляров HeaderDefect, сообщающих о любых проблемах с соответствием RFC, обнаруженных при разборе. Пакет email стремится выявлять все проблемы с соответствием. О типах дефектов, которые могут быть обнаружены, см. в модуле errors.

max_count

Максимальное количество заголовков этого типа с одинаковым name. Значение None означает отсутствие ограничения. BaseHeader значение этого атрибута — None; предполагается, что специализированные классы заголовков при необходимости переопределят это значение.

BaseHeader также предоставляет следующий метод, который вызывается кодом библиотеки email и, как правило, не должен вызываться прикладными программами:

fold(*, policy)

Возвращает строку, содержащую символы linesep в необходимом количестве для правильного переноса строк заголовка согласно policy. Значение cte_type 8bit будет обработано как 7bit, поскольку заголовки не могут содержать произвольные двоичные данные. Если utf8 равно False, данные, отличные от ASCII, будут закодированы по RFC 2047.

Сам по себе BaseHeader нельзя использовать для создания объекта заголовка. Он определяет протокол, с которым взаимодействует каждый специализированный класс заголовка для создания объекта заголовка. В частности, BaseHeader требует, чтобы специализированный класс предоставлял classmethod() с именем parse. Этот метод вызывается следующим образом:

parse(string, kwds)

kwds — это словарь, содержащий один предварительно инициализированный ключ: defects. defects — это пустой список. Метод разбора должен добавлять в этот список все обнаруженные дефекты. При возврате словарь kwds должен содержать значения как минимум для ключей decoded и defects. decoded должно быть строковым значением заголовка (то есть значением заголовка, полностью декодированным в Юникод). Метод разбора должен исходить из того, что string может содержать части, закодированные методом кодирования передачи содержимого, но также должен корректно обрабатывать все допустимые символы Юникода, чтобы разбирать незакодированные значения заголовков.

Затем BaseHeader вызывает __new__ для создания экземпляра заголовка и вызывает его метод init. Специализированному классу нужно предоставлять метод init только в том случае, если он должен задавать дополнительные атрибуты помимо тех, которые предоставляет сам BaseHeader. Такой метод init должен выглядеть следующим образом:

def init(self, /, *args, **kw):
    self._myattr = kw.pop('myattr')
    super().init(*args, **kw)

То есть любые дополнительные данные, помещённые специализированным классом в словарь kwds, следует извлечь и обработать, а оставшееся содержимое kw (и args) передать методу BaseHeader init.

class email.headerregistry.UnstructuredHeader

«Неструктурированный» заголовок — тип заголовка по умолчанию в RFC 5322. Любой заголовок, для которого не задан специальный синтаксис, считается неструктурированным. Классический пример неструктурированного заголовка — заголовок Subject.

В RFC 5322 неструктурированный заголовок представляет собой последовательность произвольного текста в наборе символов ASCII. Однако RFC 2047 определяет совместимый с RFC 5322 механизм кодирования текста, не относящегося к ASCII, в виде символов ASCII внутри значения заголовка. Когда конструктору передаётся value, содержащее закодированные слова, анализатор UnstructuredHeader преобразует такие слова в Юникод согласно правилам RFC 2047 для неструктурированного текста. Анализатор использует эвристики для попытки декодирования некоторых закодированных слов, не соответствующих требованиям. В таких случаях регистрируются дефекты, как и при обнаружении проблем, например недопустимых символов внутри закодированных слов или незакодированного текста.

Этот тип заголовка не предоставляет дополнительных атрибутов.

class email.headerregistry.DateHeader

RFC 5322 задаёт очень строгий формат дат в заголовках электронной почты. Анализатор DateHeader распознаёт этот формат, а также ряд вариантов, которые иногда встречаются на практике.

Этот тип заголовка предоставляет следующие дополнительные атрибуты:

datetime

Если значение заголовка распознаётся как корректная дата в одной из поддерживаемых форм, этот атрибут содержит экземпляр datetime, представляющий эту дату. Если часовой пояс во входной дате указан как -0000 (что означает, что дата указана в UTC, но не содержит сведений об исходном часовом поясе), то datetime будет наивным объектом datetime. Если указан конкретный сдвиг часового пояса (включая +0000), то datetime будет содержать осведомлённый объект datetime, который использует datetime.timezone для хранения сдвига часового пояса.

Значение заголовка decoded определяется форматированием datetime согласно правилам RFC 5322; то есть ему присваивается:

email.utils.format_datetime(self.datetime)

При создании DateHeader в качестве value можно передать экземпляр datetime. Это означает, например, что следующий код корректен и выполняет ожидаемые действия:

msg['Date'] = datetime(2011, 7, 15, 21)

Поскольку это наивный объект datetime, он будет интерпретирован как временная метка UTC, и полученное значение будет иметь часовой пояс -0000. Гораздо полезнее использовать функцию localtime() из модуля utils:

msg['Date'] = utils.localtime()

В этом примере заголовку даты присваиваются текущие дата и время с использованием текущего сдвига часового пояса.

class email.headerregistry.AddressHeader

Заголовки адресов относятся к числу наиболее сложных типов структурированных заголовков. Класс AddressHeader предоставляет универсальный интерфейс для любого заголовка адреса.

Этот тип заголовка предоставляет следующие дополнительные атрибуты:

groups

Кортеж объектов Group, представляющих адреса и группы, найденные в значении заголовка. Адреса, не входящие в группу, представлены в этом списке объектами Groups, содержащими один адрес, у которых display_name равен None.

addresses

Кортеж объектов Address, представляющих все отдельные адреса из значения заголовка. Если значение заголовка содержит группы, отдельные адреса из группы включаются в список в том месте, где эта группа встречается в значении (то есть список адресов «сводится» к одномерному списку).

Значение заголовка decoded будет содержать все закодированные слова, декодированные в Юникод. Имена доменов, закодированные с помощью idna, также декодируются в Юникод. Значение decoded задаётся посредством соединения значений str элементов атрибута groups с помощью ', '.

Для задания значения заголовка адреса можно использовать список объектов Address и Group в любом сочетании. Объекты Group, у которых display_name равен None, будут интерпретированы как одиночные адреса. Это позволяет скопировать список адресов, сохранив группы, используя список, полученный из атрибута groups исходного заголовка.

class email.headerregistry.SingleAddressHeader

Подкласс AddressHeader, добавляющий один дополнительный атрибут:

address

Единственный адрес, представленный значением заголовка. Если значение заголовка фактически содержит более одного адреса (что нарушало бы RFC при использовании стандартной политики policy), обращение к этому атрибуту вызовет исключение ValueError.

Многие из перечисленных выше классов также имеют вариант Unique (например, UniqueUnstructuredHeader). Единственное отличие состоит в том, что у варианта Unique значение max_count равно 1.

class email.headerregistry.MIMEVersionHeader

Для заголовка MIME-Version существует только одно допустимое значение — 1.0. Для обеспечения совместимости с будущими версиями этот класс заголовка поддерживает и другие допустимые номера версий. Если номер версии имеет допустимое значение согласно RFC 2045, объект заголовка будет содержать значения, отличные от None, для следующих атрибутов:

version

Номер версии в виде строки без пробельных символов и/или комментариев.

major

Старший номер версии в виде целого числа

minor

Младший номер версии в виде целого числа

class email.headerregistry.ParameterizedMIMEHeader

Все заголовки MIME начинаются с префикса «Content-». Для каждого конкретного заголовка предусмотрено определённое значение, описанное в разделе, посвящённом соответствующему классу. Некоторые из них также могут принимать список дополнительных параметров общего формата. Этот класс служит базовым для всех заголовков MIME, принимающих параметры.

params

Словарь, сопоставляющий имена параметров их значениям.

class email.headerregistry.ContentTypeHeader

Класс ParameterizedMIMEHeader, обрабатывающий заголовок Content-Type.

content_type

Строка типа содержимого в формате maintype/subtype.

maintype
subtype
class email.headerregistry.ContentDispositionHeader

Класс ParameterizedMIMEHeader, обрабатывающий заголовок Content-Disposition.

content_disposition

inline и attachment — единственные широко используемые допустимые значения.

class email.headerregistry.ContentTransferEncoding

Обрабатывает заголовок Content-Transfer-Encoding.

cte

Допустимые значения: 7bit, 8bit, base64 и quoted-printable. Дополнительные сведения см. в RFC 2045.

class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)

Это фабрика, используемая по умолчанию объектом EmailPolicy. HeaderRegistry динамически создаёт класс для экземпляра заголовка, используя base_class и специализированный класс, полученный из хранящегося в ней реестра. Если указанное имя заголовка отсутствует в реестре, в качестве специализированного класса используется класс, заданный параметром default_class. Если use_default_map равно True (значение по умолчанию), стандартное сопоставление имён заголовков с классами копируется в реестр при инициализации. base_class всегда является последним классом в списке __bases__ созданного класса.

Сопоставления по умолчанию:

subject:

UniqueUnstructuredHeader

date:

UniqueDateHeader

resent-date:

DateHeader

orig-date:

UniqueDateHeader

sender:

UniqueSingleAddressHeader

resent-sender:

SingleAddressHeader

to:

UniqueAddressHeader

resent-to:

AddressHeader

cc:

UniqueAddressHeader

resent-cc:

AddressHeader

bcc:

UniqueAddressHeader

resent-bcc:

AddressHeader

from:

UniqueAddressHeader

resent-from:

AddressHeader

reply-to:

UniqueAddressHeader

mime-version:

MIMEVersionHeader

content-type:

ContentTypeHeader

content-disposition:

ContentDispositionHeader

content-transfer-encoding:

ContentTransferEncodingHeader

message-id:

MessageIDHeader

У HeaderRegistry есть следующие методы:

map_to_type(self, name, cls)

name — имя заголовка, для которого задаётся сопоставление. В реестре оно будет преобразовано к нижнему регистру. cls — специализированный класс, который вместе с base_class будет использоваться для создания класса, создающего экземпляры заголовков с именем name.

__getitem__(name)

Создаёт и возвращает класс для обработки заголовка name.

__call__(name, value)

Получает из реестра специализированный заголовок, связанный с name (используя default_class, если name отсутствует в реестре), и объединяет его с base_class, чтобы создать класс; вызывает конструктор созданного класса, передавая ему тот же список аргументов, и, наконец, возвращает созданный экземпляр класса.

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

class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)

Класс для представления адреса электронной почты. Общий формат адреса:

[display_name] <username@domain>

или:

username@domain

где каждая часть должна соответствовать определённым синтаксическим правилам, изложенным в RFC 5322.

Для удобства вместо username и domain можно указать addr_spec; в этом случае username и domain будут извлечены из addr_spec. Значение addr_spec должно быть строкой в кавычках, соответствующей RFC; если это не так, Address вызовет ошибку. Символы Юникода допустимы и при сериализации будут соответствующим образом закодированы. Однако согласно RFC символы Юникода не допускаются в части адреса с именем пользователя.

display_name

Отображаемое имя адреса, если оно есть, без кавычек. Если у адреса нет отображаемого имени, значение этого атрибута будет пустой строкой.

username

Часть адреса username без кавычек.

domain

Часть адреса domain.

addr_spec

Часть адреса username@domain, заключённая в кавычки должным образом для использования в качестве отдельного адреса (вторая форма, показанная выше). Этот атрибут нельзя изменять.

__str__()

Значение str объекта — это адрес, заключённый в кавычки согласно правилам RFC 5322, но без кодирования передачи содержимого для символов, отличных от ASCII.

Для поддержки SMTP (RFC 5321) Address обрабатывает один особый случай: если username и domain — обе пустые строки (или None), то строковое значение Address равно <>.

class email.headerregistry.Group(display_name=None, addresses=None)

Класс, используемый для представления группы адресов. Общий формат группы адресов:

display_name: [address-list];

Для удобства обработки списков адресов, состоящих из сочетания групп и отдельных адресов, Group также можно использовать для представления отдельных адресов, не входящих в группу: для этого следует задать display_name значение None и передать список отдельных адресов в качестве addresses.

display_name

Значение display_name группы. Если оно равно None и в списке addresses содержится ровно один Address, то Group представляет отдельный адрес, не входящий в группу.

addresses

Кортеж, который может быть пустым, из объектов Address, представляющих адреса в группе.

__str__()

Значение str объекта Group форматируется в соответствии с RFC 5322, но без кодирования передачи содержимого для символов, не входящих в ASCII. Если display_name равен none и в списке addresses содержится один Address, значение str будет таким же, как str этого единственного Address.

Сноски

[1]

Изначально добавлен в версии 3.3 как предварительный модуль

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/email.headerregistry.html

Spec-Zone.ru

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