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– это пустой список. Метод parse должен добавлять любые обнаруженные дефекты в этот список. При возврате словарьkwdsдолжен содержать значения по крайней мере для ключейdecoded,defectsиparse_tree.decodedдолжно быть строковым значением заголовка (то есть значением заголовка, полностью декодированным в Unicode).parse_treeустанавливается в дерево разбора, полученное при разборе заголовка. Метод parse должен предполагать, что строка может содержать части, закодированные с помощью 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.
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
UnstructuredHeaderparser 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¶
Словарь, сопоставляющий имена параметров со значениями параметров.
Изменено в версии 3.15: Теперь это
frozendictвместоtypes.MappingProxyType.
- 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.ContentTransferEncodingHeader¶
Обрабатывает заголовок Content-Transfer-Encoding.
- 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представляет отдельный адрес, не входящий в группу.
Сноски
Эта страница – перевод. Оригинал на английском – docs.python.org. Нашли неточность? Сообщите нам.