Spec-Zone.ru › Python 3.12

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

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

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

Затем BaseHeader вызывает __new__ для создания экземпляра заголовка, после чего вызывает его метод 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.

Для удобства можно указать 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.

Сноски

[1]

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

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

Spec-Zone.ru

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