email.headerregistry.md · Markdown – Документация Python
Документация Python неофициальный перевод

email.headerregistry.md

352 строк · 31.0 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.16/library/email.headerregistry.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `email.headerregistry`: настраиваемые объекты заголовков89**Исходный код:** [Lib/email/headerregistry.py](https://python-all.ru/src/main/Lib/email/headerregistry.py)1011---1213Добавлено в версии 3.6: [\[1\]](https://python-all.ru/3.16/library/email.headerregistry.html#id2)1415Заголовки представлены настраиваемыми подклассами [`str`](https://python-all.ru/3.16/library/stdtypes.html#str). Конкретный класс, используемый для представления данного заголовка, определяется [`header_factory`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy.header_factory) [`policy`](https://python-all.ru/3.16/library/email.policy.html#module-email.policy), действующей на момент создания заголовков. В этом разделе описаны конкретные `header_factory`, реализованные в пакете email для обработки [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html)-совместимых сообщений электронной почты. Они не только предоставляют настраиваемые объекты заголовков для различных типов заголовков, но и содержат механизм расширения, позволяющий приложениям добавлять собственные типы заголовков.1617При использовании любого объекта политики, производного от [`EmailPolicy`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy), все заголовки создаются [`HeaderRegistry`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.HeaderRegistry) и имеют [`BaseHeader`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.BaseHeader) в качестве своего последнего базового класса. Каждый класс заголовков имеет дополнительный базовый класс, определяемый типом заголовка. Например, у многих заголовков другим базовым классом является [`UnstructuredHeader`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.UnstructuredHeader). Специализированный второй класс для заголовка определяется по имени заголовка с помощью таблицы поиска, хранящейся в `HeaderRegistry`. Всё это прозрачно управляется для типичных прикладных программ, но для более сложных приложений предусмотрены интерфейсы для изменения поведения по умолчанию.1819В следующих разделах сначала описаны базовые классы заголовков и их атрибуты, затем API для изменения поведения [`HeaderRegistry`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.HeaderRegistry), и, наконец, вспомогательные классы, используемые для представления данных, полученных при разборе структурированных заголовков.2021#### `class email.headerregistry.BaseHeader(name, value)`2223*name* и *value* передаются в `BaseHeader` из вызова [`header_factory`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy.header_factory). Строковое значение любого объекта заголовка – это *value*, полностью декодированное в Unicode.2425Этот базовый класс определяет следующие свойства, доступные только для чтения:2627#### `name`2829Имя заголовка (часть поля до двоеточия). Это в точности то значение, которое было передано в вызове [`header_factory`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy.header_factory) для *name*; то есть регистр сохраняется.3031#### `defects`3233Кортеж экземпляров [`HeaderDefect`](https://python-all.ru/3.16/library/email.errors.html#email.errors.HeaderDefect), сообщающих о любых проблемах с соответствием RFC, обнаруженных во время разбора. Пакет email старается быть полным в выявлении проблем соответствия. См. модуль [`errors`](https://python-all.ru/3.16/library/email.errors.html#module-email.errors) для обсуждения типов дефектов, которые могут быть зарегистрированы.3435#### `max_count`3637Максимальное количество заголовков данного типа, которые могут иметь одинаковое `name`. Значение `None` означает неограниченное количество. Значение `BaseHeader` для этого атрибута равно `None`; предполагается, что специализированные классы заголовков будут переопределять это значение по мере необходимости.3839`BaseHeader` также предоставляет следующий метод, который вызывается библиотечным кодом email и, как правило, не должен вызываться прикладными программами:4041#### `fold(*, policy)`4243Возвращает строку, содержащую символы [`linesep`](https://python-all.ru/3.16/library/email.policy.html#email.policy.Policy.linesep), необходимые для правильной укладки заголовка в соответствии с *policy*. Значение [`cte_type`](https://python-all.ru/3.16/library/email.policy.html#email.policy.Policy.cte_type), равное `8bit`, будет обрабатываться так, как если бы оно было `7bit`, поскольку заголовки не могут содержать произвольные двоичные данные. Если [`utf8`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy.utf8) равно `False`, не-ASCII данные будут закодированы по [**RFC 2047**](https://python-all.ru/3.16/library/email.headerregistry.html).4445Сам по себе `BaseHeader` не может использоваться для создания объекта заголовка. Он определяет протокол, с которым взаимодействует каждый специализированный заголовок для создания объекта заголовка. В частности, `BaseHeader` требует, чтобы специализированный класс предоставлял [`classmethod()`](https://python-all.ru/3.16/library/functions.html#classmethod) с именем `parse`. Этот метод вызывается следующим образом:4647```python48parse(string, kwds)49```5051`kwds` – это словарь, содержащий один предварительно инициализированный ключ, `defects`. `defects` – это пустой список. Метод parse должен добавлять любые обнаруженные дефекты в этот список. При возврате словарь `kwds` *должен* содержать значения по крайней мере для ключей `decoded`, `defects` и `parse_tree`. `decoded` должно быть строковым значением заголовка (то есть значением заголовка, полностью декодированным в Unicode). `parse_tree` устанавливается в дерево разбора, полученное при разборе заголовка. Метод parse должен предполагать, что *строка* может содержать части, закодированные с помощью content-transfer-encoding, но также должен корректно обрабатывать все допустимые символы Unicode, чтобы иметь возможность разбирать незакодированные значения заголовков.5253Затем `__new__` из `BaseHeader` создаёт экземпляр заголовка и вызывает его метод `init`. Специализированному классу нужно предоставить метод `init` только в том случае, если он хочет установить дополнительные атрибуты, выходящие за рамки тех, что предоставляет сам `BaseHeader`. Такой метод `init` должен выглядеть следующим образом:5455```python56def init(self, /, *args, **kw):57    self._myattr = kw.pop('myattr')58    super().init(*args, **kw)59```6061То есть всё лишнее, что специализированный класс поместил в словарь `kwds`, должно быть удалено и обработано, а оставшееся содержимое `kw``args`) передано методу `init` из `BaseHeader`.6263#### `class email.headerregistry.UnstructuredHeader`6465«Неструктурированный» заголовок – это тип заголовка по умолчанию в [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html). Любой заголовок, не имеющий заданного синтаксиса, считается неструктурированным. Классический пример неструктурированного заголовка – *Subject*.6667In [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html), an unstructured header is a run of arbitrary text in the ASCII character set. [**RFC 2047**](https://python-all.ru/3.16/library/email.headerregistry.html), however, has an [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html) 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 `UnstructuredHeader` parser converts such encoded words into unicode, following the [**RFC 2047**](https://python-all.ru/3.16/library/email.headerregistry.html) 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.6869Этот тип заголовка не предоставляет дополнительных атрибутов.7071#### `class email.headerregistry.DateHeader`7273[**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html) задаёт очень конкретный формат для дат в заголовках электронной почты. Анализатор `DateHeader` распознаёт этот формат даты, а также множество вариантов, которые иногда встречаются «в дикой природе».7475Этот тип заголовка предоставляет следующие дополнительные атрибуты:7677#### `datetime`7879Если значение заголовка можно распознать как допустимую дату в том или ином формате, этот атрибут будет содержать экземпляр [`datetime`](https://python-all.ru/3.16/library/datetime.html#datetime.datetime), представляющий эту дату. Если часовой пояс входной даты указан как `-0000` (что означает, что дата в UTC, но не содержит информации об исходном часовом поясе), тогда [`datetime`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.DateHeader.datetime) будет наивным `datetime`. Если же найден конкретный сдвиг часового пояса (включая `+0000`), тогда `datetime` будет содержать осведомлённый `datetime`, который использует [`datetime.timezone`](https://python-all.ru/3.16/library/datetime.html#datetime.timezone) для записи сдвига часового пояса.8081Значение `decoded` заголовка определяется форматированием `datetime` в соответствии с правилами [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html); то есть оно устанавливается в:8283```python84email.utils.format_datetime(self.datetime)85```8687При создании `DateHeader`, *value* может быть экземпляром [`datetime`](https://python-all.ru/3.16/library/datetime.html#datetime.datetime). Это означает, например, что следующий код корректен и делает то, что можно ожидать:8889```python90msg['Date'] = datetime(2011, 7, 15, 21)91```9293Поскольку это наивный `datetime`, он будет интерпретироваться как временная метка UTC, и результирующее значение будет иметь часовой пояс `-0000`. Гораздо полезнее использовать функцию [`localtime()`](https://python-all.ru/3.16/library/email.utils.html#email.utils.localtime) из модуля [`utils`](https://python-all.ru/3.16/library/email.utils.html#module-email.utils):9495```python96msg['Date'] = utils.localtime()97```9899В этом примере заголовок даты устанавливается в текущее время и дату с использованием текущего сдвига часового пояса.100101#### `class email.headerregistry.AddressHeader`102103Заголовки адресов – одни из самых сложных структурированных типов заголовков. Класс `AddressHeader` предоставляет универсальный интерфейс для любого заголовка адреса.104105Этот тип заголовка предоставляет следующие дополнительные атрибуты:106107#### `groups`108109Кортеж объектов [`Group`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.Group), кодирующих адреса и группы, найденные в значении заголовка. Адреса, не входящие в группу, представляются в этом списке как одноадресные `Groups`, чьё [`display_name`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.Group.display_name) равно `None`.110111#### `addresses`112113Кортеж объектов [`Address`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.Address), кодирующих все отдельные адреса из значения заголовка. Если значение заголовка содержит группы, отдельные адреса из группы включаются в список в том месте, где группа встречается в значении (то есть список адресов «уплощается» до одномерного списка).114115Значение `decoded` заголовка будет содержать все закодированные слова, декодированные в Unicode. Закодированные доменные имена [`idna`](https://python-all.ru/3.16/library/codecs.html#module-encodings.idna) также декодируются в Unicode. Значение `decoded` устанавливается путём [объединения](https://python-all.ru/3.16/library/stdtypes.html#meth-str-join) значения [`str`](https://python-all.ru/3.16/library/stdtypes.html#str) элементов атрибута `groups` с `', '`.116117Список объектов [`Address`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.Address) и [`Group`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.Group) в любой комбинации может использоваться для установки значения заголовка адреса. Объекты `Group`, у которых `display_name` равно `None`, будут интерпретироваться как отдельные адреса, что позволяет копировать список адресов с сохранением групп, используя список, полученный из атрибута `groups` исходного заголовка.118119#### `class email.headerregistry.SingleAddressHeader`120121Подкласс [`AddressHeader`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.AddressHeader), добавляющий один дополнительный атрибут:122123#### `address`124125Единственный адрес, закодированный значением заголовка. Если значение заголовка фактически содержит более одного адреса (что будет нарушением RFC при стандартном [`policy`](https://python-all.ru/3.16/library/email.policy.html#module-email.policy)), обращение к этому атрибуту приведёт к [`ValueError`](https://python-all.ru/3.16/library/exceptions.html#ValueError).126127Многие из перечисленных выше классов также имеют вариант `Unique` (например, `UniqueUnstructuredHeader`). Единственное отличие состоит в том, что в варианте `Unique` [`max_count`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.BaseHeader.max_count) установлено в 1.128129#### `class email.headerregistry.MIMEVersionHeader`130131На самом деле существует только одно допустимое значение для заголовка *MIME-Version*, и это `1.0`. Для обеспечения будущей совместимости этот класс заголовка поддерживает другие корректные номера версий. Если номер версии имеет допустимое значение в соответствии с [**RFC 2045**](https://python-all.ru/3.16/library/email.headerregistry.html), то объект заголовка будет иметь не-`None` значения для следующих атрибутов:132133#### `version`134135Номер версии в виде строки, из которой удалены все пробелы и/или комментарии.136137#### `major`138139Номер основной версии в виде целого числа.140141#### `minor`142143Номер дополнительной версии в виде целого числа.144145#### `class email.headerregistry.ParameterizedMIMEHeader`146147Все MIME-заголовки начинаются с префикса «Content-». Каждый конкретный заголовок имеет определённое значение, описанное в классе этого заголовка. Некоторые также могут принимать список дополнительных параметров, имеющих общий формат. Этот класс служит базовым для всех MIME-заголовков, принимающих параметры.148149#### `params`150151Словарь, сопоставляющий имена параметров со значениями параметров.152153Изменено в версии 3.15: Теперь это [`frozendict`](https://python-all.ru/3.16/library/stdtypes.html#frozendict) вместо [`types.MappingProxyType`](https://python-all.ru/3.16/library/types.html#types.MappingProxyType).154155#### `class email.headerregistry.ContentTypeHeader`156157Класс [`ParameterizedMIMEHeader`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.ParameterizedMIMEHeader), обрабатывающий заголовок *Content-Type*.158159#### `content_type`160161Строка типа содержимого в формате `maintype/subtype`.162163#### `maintype`164165#### `subtype`166167#### `class email.headerregistry.ContentDispositionHeader`168169Класс [`ParameterizedMIMEHeader`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.ParameterizedMIMEHeader), обрабатывающий заголовок *Content-Disposition*.170171#### `content_disposition`172173`inline` и `attachment` – единственные общеупотребительные допустимые значения.174175#### `class email.headerregistry.ContentTransferEncodingHeader`176177Обрабатывает заголовок *Content-Transfer-Encoding*.178179#### `cte`180181Допустимые значения: `7bit`, `8bit`, `base64` и `quoted-printable`. Подробнее см. [**RFC 2045**](https://python-all.ru/3.16/library/email.headerregistry.html).182183#### `class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)`184185Это фабрика, используемая [`EmailPolicy`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy) по умолчанию. `HeaderRegistry` динамически создаёт класс для построения экземпляра заголовка, используя *base\_class* и специализированный класс из своего внутреннего реестра. Если заданное имя заголовка отсутствует в реестре, в качестве специализированного используется класс, указанный в *default\_class*. Когда *use\_default\_map* равно `True` (по умолчанию), стандартное сопоставление имён заголовков с классами копируется в реестр при инициализации. *base\_class* всегда является последним классом в списке [`__bases__`](https://python-all.ru/3.16/reference/datamodel.html#type.__bases__) создаваемого класса.186187Стандартные сопоставления:188189> **тема:**190>191> UniqueUnstructuredHeader192>193> **date:**194>195> UniqueDateHeader196>197> **resent-date:**198>199> DateHeader200>201> **orig-date:**202>203> UniqueDateHeader204>205> **sender:**206>207> UniqueSingleAddressHeader208>209> **resent-sender:**210>211> SingleAddressHeader212>213> **to:**214>215> UniqueAddressHeader216>217> **resent-to:**218>219> AddressHeader220>221> **cc:**222>223> UniqueAddressHeader224>225> **resent-cc:**226>227> AddressHeader228>229> **bcc:**230>231> UniqueAddressHeader232>233> **resent-bcc:**234>235> AddressHeader236>237> **from:**238>239> UniqueAddressHeader240>241> **resent-from:**242>243> AddressHeader244>245> **reply-to:**246>247> UniqueAddressHeader248>249> **mime-version:**250>251> MIMEVersionHeader252>253> **content-type:**254>255> ContentTypeHeader256>257> **content-disposition:**258>259> ContentDispositionHeader260>261> **content-transfer-encoding:**262>263> ContentTransferEncodingHeader264>265> **message-id:**266>267> MessageIDHeader268269`HeaderRegistry` имеет следующие методы:270271#### `map_to_type(self, name, cls)`272273*name* – это имя сопоставляемого заголовка. Оно будет преобразовано в нижний регистр в реестре. *cls* – это специализированный класс, используемый, вместе с *base\_class*, для создания класса, с помощью которого создаются экземпляры заголовков, соответствующих *name*.274275#### `__getitem__(name)`276277Создаёт и возвращает класс для создания заголовка *name*.278279#### `__call__(name, value)`280281Извлекает из реестра специализированный заголовок, связанный с *name* (используя *default\_class*, если *name* отсутствует в реестре), и объединяет его с *base\_class* для получения нового класса, вызывает конструктор созданного класса, передавая ему тот же список аргументов, и, наконец, возвращает полученный экземпляр класса.282283Следующие классы используются для представления данных, извлечённых при разборе структурированных заголовков. В общем случае прикладная программа может применять их для формирования структурированных значений, присваиваемых конкретным заголовкам.284285#### `class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)`286287Класс, используемый для представления адреса электронной почты. Общий вид адреса:288289```python290[display_name] <username@domain>291```292293или:294295```python296username@domain297```298299где каждая часть должна соответствовать определённым правилам синтаксиса, изложенным в [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html).300301Для удобства можно указать *addr\_spec* вместо *username* и *domain*; в этом случае *username* и *domain* будут извлечены из *addr\_spec*. Значение *addr\_spec* должно быть строкой, правильно экранированной в соответствии с RFC; если это не так, `Address` вызовет ошибку. Допускаются символы Unicode, которые будут корректно закодированы при сериализации. Однако согласно RFC, Unicode *не* разрешён в части имени пользователя адреса.302303#### `display_name`304305Часть адреса, содержащая отображаемое имя, если оно есть, с удалёнными кавычками. Если у адреса нет отображаемого имени, этот атрибут будет пустой строкой.306307#### `username`308309Часть адреса `username`, с удалёнными кавычками.310311#### `domain`312313Часть адреса `domain`.314315#### `addr_spec`316317Часть адреса `username@domain`, правильно экранированная для использования в качестве «голого» адреса (вторая форма, показанная выше). Этот атрибут не изменяем.318319#### `__str__()`320321Значение `str` объекта – это адрес, экранированный в соответствии с правилами [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html), но без кодирования передачи содержимого для любых не-ASCII символов.322323Для поддержки SMTP ([**RFC 5321**](https://python-all.ru/3.16/library/email.headerregistry.html)) `Address` обрабатывает один особый случай: если `username` и `domain` оба являются пустыми строками (или `None`), то строковое значение `Address` равно `<>`.324325#### `class email.headerregistry.Group(display_name=None, addresses=None)`326327Класс, используемый для представления группы адресов. Общий вид группы адресов:328329```python330display_name: [address-list];331```332333Для удобства обработки списков адресов, состоящих из смеси групп и отдельных адресов, `Group` также может использоваться для представления отдельных адресов, не входящих в группу, путём установки *display\_name* в `None` и передачи списка из одного адреса в качестве *addresses*.334335#### `display_name`336337`display_name` группы. Если оно равно `None` и в `addresses` есть ровно один `Address`, то `Group` представляет отдельный адрес, не входящий в группу.338339#### `addresses`340341Возможно пустой кортеж объектов [`Address`](https://python-all.ru/3.16/library/email.headerregistry.html#email.headerregistry.Address), представляющих адреса в группе.342343#### `__str__()`344345Значение `str` объекта `Group` форматируется в соответствии с [**RFC 5322**](https://python-all.ru/3.16/library/email.headerregistry.html), но без кодирования передачи содержимого для любых не-ASCII символов. Если `display_name` равно None и в списке `addresses` есть один `Address`, то значение `str` будет совпадать со значением `str` этого единственного `Address`.346347Сноски348349\[[1](https://python-all.ru/3.16/library/email.headerregistry.html#id1)\]350351Изначально добавлен в версии 3.3 как [временный модуль](https://python-all.ru/3.16/glossary.html#term-provisional-package)352