Документация Python неофициальный перевод

email.headerregistry: настраиваемые объекты заголовковemail.headerregistry: Custom Header Objects

Исходный код: 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, полностью декодированное в Unicode.

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

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

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

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

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

class email.headerregistry.UnstructuredHeader

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

In RFC 5322, an unstructured header is a run of arbitrary text in the ASCII character set. RFC 2047, however, has an RFC 5322 compatible mechanism for encoding non-ASCII text as ASCII characters within a header value. When a value containing encoded words is passed to the constructor, the UnstructuredHeader parser converts such encoded words into unicode, following the RFC 2047 rules for unstructured text. The parser uses heuristics to attempt to decode certain non-compliant encoded words. Defects are registered in such cases, as well as defects for issues such as invalid characters within the encoded words or the non-encoded text.

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

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 заголовка будет содержать все закодированные слова, декодированные в Unicode. Закодированные доменные имена idna также декодируются в Unicode. Значение 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__ создаваемого класса.

Стандартные сопоставления:

тема:

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.

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

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.

Сноски