email.headerregistry
: Пользовательские объекты заголовка¶
Исходный код: Lib/email/headerregistry.py
Добавлено в версии 3.6: [1]
Заголовки представлены настраиваемыми подклассами типа str
. Конкретный класс, используемый для представления данного заголовка, определяется значением header_factory
из policy
, которое применяется при создании заголовков. В этом разделе описывается конкретный header_factory
, реализованный в пакете электронной почты для обработки RFC 5322 совместимых сообщений электронной почты, который не только предоставляет настраиваемые объекты заголовков для различных типов заголовков, но также предоставляет приложениям механизм расширения для добавления своих собственных пользовательских типов заголовков.
При использовании любого из объектов политики, производных от EmailPolicy
, все заголовки создаются с помощью HeaderRegistry
и имеют BaseHeader
в качестве последнего базового класса. У каждого класса заголовков есть дополнительный базовый класс, который определяется типом заголовка. Например, у многих заголовков класс UnstructuredHeader
является другим базовым классом. Специализированный второй класс для заголовка определяется по имени заголовка с использованием таблицы поиска, хранящейся в HeaderRegistry
. Все это управляется прозрачно для обычной прикладной программы, но предусмотрены интерфейсы для изменения поведения по умолчанию для использования более сложными приложениями.
В приведенных ниже разделах сначала описываются базовые классы заголовков и их атрибуты, затем API для изменения поведения HeaderRegistry
и, наконец, вспомогательные классы, используемые для представления данных, проанализированных из структурированных заголовков.
- class email.headerregistry.BaseHeader(name, value)¶
имя и значение передаются в
BaseHeader
из вызоваheader_factory
. Строковым значением любого объекта header является значение, полностью декодированное в unicode.Этот базовый класс определяет следующие свойства, доступные только для чтения:
- name¶
Имя заголовка (часть поля перед „:“). Это именно то значение, которое было передано при вызове
header_factory
для name; то есть регистр сохранен.
- defects¶
Набор
HeaderDefect
экземпляров, сообщающих о любых проблемах с соблюдением требований RFC, обнаруженных во время синтаксического анализа. Пакет электронной почты пытается предоставить полную информацию об обнаружении проблем с соблюдением требований. Смотрите модульerrors
для обсуждения типов дефектов, о которых может быть сообщено.
- max_count¶
Максимальное количество заголовков этого типа, которые могут иметь одинаковое значение
name
. ЗначениеNone
означает неограниченное. ЗначениемBaseHeader
для этого атрибута являетсяNone
; ожидается, что специализированные классы заголовков будут переопределять это значение по мере необходимости.
BaseHeader
также предоставляет следующий метод, который вызывается кодом библиотеки электронной почты и, как правило, не должен вызываться прикладными программами:- fold(*, policy)¶
Возвращает строку, содержащую
linesep
символов, необходимых для правильного сворачивания заголовка в соответствии с политикой.cte_type
из8bit
будет обрабатываться так, как если бы это было7bit
, поскольку заголовки могут не содержать произвольных двоичных данных. Еслиutf8
равноFalse
, данные, отличные от ASCII, будут закодированы в RFC 2047.
BaseHeader
сам по себе не может использоваться для создания объекта header. Он определяет протокол, с которым взаимодействует каждый специализированный заголовок для создания объекта header. В частности,BaseHeader
требует, чтобы специализированный класс предоставлялclassmethod()
с именемparse
. Этот метод вызывается следующим образом:parse(string, kwds)
kwds
- это словарь, содержащий один предварительно инициализированный ключ,defects
.defects
- это пустой список. Метод parse должен добавить к этому списку все обнаруженные дефекты. При возврате словарьkwds
должен содержать значения, по крайней мере, для ключейdecoded
иdefects
.decoded
должно быть строковым значением заголовка (то есть значением заголовка, полностью декодированным в unicode). Метод parse должен предполагать, что string может содержать части, закодированные для передачи содержимого, но также должен корректно обрабатывать все допустимые символы unicode, чтобы он мог анализировать некодированные значения заголовка.BaseHeader
’s__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 в значении заголовка. Когда конструктору передается значение, содержащее закодированные слова, синтаксический анализатор
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
значением * может быть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
задается с помощью joining, а значение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.
- 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__
сгенерированного класса.По умолчанию используются следующие сопоставления:
- предмет:
Уникальный структурированный заголовок
- дата:
Уникальный заголовок данных
- дата повторной отправки:
Заголовок даты
- первоначальная дата:
Уникальный заголовок данных
- отправитель:
Уникальный заголовок Singleaddresssheader
- отправитель жалобы:
Заголовок с одним адресом
- к:
Уникальный адресный заголовок
- негодовать-на:
Адресный справочник
- куб.см:
Уникальный адресный заголовок
- возмущаться-cc:
Адресный справочник
- оцк:
Уникальный адресный заголовок
- возмущаться-bcc:
Адресный справочник
- от:
Уникальный адресный заголовок
- возмущаться-от:
Адресный справочник
- ответить-кому:
Уникальный адресный заголовок
- мим-версия:
Заголовок Mimeversion
- тип содержимого:
ContentTypeHeader - заголовок типа содержимого
- содержание-расположение:
ContentDispositionHeader - Заголовок размещения содержимого
- передача контента-кодирование:
Заголовок ContentTransferEncodingHeader
- идентификатор сообщения:
Заголовок сообщения
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, юникод * не* разрешен в части имени пользователя адреса.- 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
и предоставления списка единый адрес в виде адресов.- display_name¶
display_name
из группы. Если этоNone
и вaddresses
есть ровно одинAddress
, тоGroup
представляет собой отдельный адрес, который не входит в группу.
Сноски