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_type8bitрассматривается как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.
-
Сноски
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/email.headerregistry.html