Spec-Zone.ru › Python 3.11

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. Строковое значение любого объекта заголовка — это полностью декодированное в Unicode значение value.

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

name

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

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

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

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

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

class email.headerregistry.UnstructuredHeader

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

В RFC 5322 неструктурированный заголовок представляет собой последовательность произвольного текста в наборе символов ASCII. Однако в RFC 2047 предусмотрен совместимый с RFC 5322 механизм кодирования текста, не входящего в ASCII, в виде ASCII-символов внутри значения заголовка. Когда конструктору передаётся value, содержащий кодированные слова, анализатор UnstructuredHeader преобразует такие слова в Unicode, следуя правилам 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 заголовка содержит все кодированные слова, декодированные в 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__ созданного класса.

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

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 (если name отсутствует в реестре, используется default_class), и объединяет его с 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 вызовет ошибку. Символы Unicode разрешены и при сериализации будут соответствующим образом закодированы. Однако согласно RFC символы Unicode не допускаются в части адреса, содержащей имя пользователя.

display_name

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

username

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

domain

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

addr_spec

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

__str__()

Значение объекта str — это адрес, заключённый в кавычки согласно правилам RFC 5322, но без Content Transfer Encoding для символов, не входящих в 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/email.headerregistry.html

Spec-Zone.ru

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