email.headerregistry
: Custom Header Objects¶
Вихідний код: Lib/email/headerregistry.py
Added in version 3.6: [1]
Заголовки представлені налаштованими підкласами str
. Конкретний клас, який використовується для представлення даного заголовка, визначається header_factory
policy
, що діє під час створення заголовків. У цьому розділі описано конкретну header_factory
, реалізовану пакетом електронної пошти для обробки RFC 5322 сумісних повідомлень електронної пошти, яка не тільки надає налаштовані об’єкти заголовків для різних типів заголовків, але також забезпечує механізм розширення для додатків для додавання своїх власні типи заголовків.
При використанні будь-якого з об’єктів політики, отриманих від EmailPolicy
, усі заголовки створюються HeaderRegistry
і мають BaseHeader
як останній базовий клас. Кожен клас заголовка має додатковий базовий клас, який визначається типом заголовка. Наприклад, багато заголовків мають клас UnstructuredHeader
як інший базовий клас. Спеціалізований другий клас для заголовка визначається назвою заголовка за допомогою таблиці пошуку, що зберігається в HeaderRegistry
. Усім цим керується прозоро для типової прикладної програми, але надаються інтерфейси для зміни типової поведінки для використання більш складними програмами.
У розділах нижче спочатку описані базові класи заголовків та їх атрибути, потім API для зміни поведінки HeaderRegistry
і, нарешті, класи підтримки, які використовуються для представлення даних, проаналізованих із структурованих заголовків.
- class email.headerregistry.BaseHeader(name, value)¶
name і value передаються в
BaseHeader
з викликуheader_factory
. Рядкове значення будь-якого об’єкта заголовка є значенням, повністю декодованим у Юнікод.Цей базовий клас визначає наступні властивості лише для читання:
- name¶
Назва заголовка (частина поля перед «:»). Це саме значення, передане у виклику
header_factory
для name; тобто регістр зберігається.
- defects¶
Кортеж екземплярів
HeaderDefect
, які повідомляють про будь-які проблеми відповідності RFC, виявлені під час аналізу. Пакет електронної пошти намагається бути повним щодо виявлення проблем відповідності. Перегляньте модульerrors
для обговорення типів дефектів, про які можна повідомити.
- max_count¶
Максимальна кількість заголовків цього типу, які можуть мати однакову назву. Значення
None
означає необмежений. ЗначенняBaseHeader
для цього атрибута єNone
; очікується, що спеціалізовані класи заголовків замінять це значення за потреби.
BaseHeader
також надає наступний метод, який викликається кодом бібліотеки електронної пошти і, як правило, не повинен викликатися прикладними програмами:- fold(*, policy)¶
Повертає рядок, що містить символи
linesep
, необхідні для правильного згортання заголовка відповідно до policy.cte_type
8bit
буде розглядатися як7bit
, оскільки заголовки не можуть містити довільних двійкових даних. Якщоutf8
має значенняFalse
, дані, відмінні від ASCII, будуть закодовані RFC 2047.
BaseHeader
сам по собі не може використовуватися для створення об’єкта заголовка. Він визначає протокол, з яким співпрацює кожен спеціалізований заголовок, щоб створити об’єкт заголовка. Зокрема,BaseHeader
вимагає, щоб спеціалізований клас надававclassmethod()
під назвоюparse
. Цей метод називається наступним чином:parse(string, kwds)
kwds
— це словник, що містить один попередньо ініціалізований ключ,defects
.дефекти
– порожній список. Метод аналізу має додати всі виявлені дефекти до цього списку. Після повернення словникkwds
має містити значення принаймні для ключівdecoded
іdefects
.decoded
має бути значенням рядка для заголовка (тобто, значення заголовка, повністю декодоване в Юнікод). Метод синтаксичного аналізу має припускати, що рядок може містити частини, закодовані перенесенням вмісту, але також має правильно обробляти всі дійсні символи Unicode, щоб він міг аналізувати незакодовані значення заголовка.Потім
__new__
BaseHeader
створює екземпляр заголовка та викликає його метод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
перетворює такі закодовані слова в юнікод, дотримуючись правил RFC 2047 для неструктурованого тексту. Синтаксичний аналізатор використовує евристику, щоб спробувати декодувати певні невідповідні закодовані слова. У таких випадках реєструються дефекти, а також такі дефекти, як недійсні символи в закодованих словах або незакодований текст.Цей тип заголовка не містить додаткових атрибутів.
- class email.headerregistry.DateHeader¶
RFC 5322 визначає дуже специфічний формат для дат у заголовках електронних листів. Синтаксичний аналізатор
DateHeader
розпізнає цей формат дати, а також розпізнає низку варіантних форм, які іноді зустрічаються «в дикій природі».Цей тип заголовка надає такі додаткові атрибути:
- datetime¶
If the header value can be recognized as a valid date of one form or another, this attribute will contain a
datetime
instance representing that date. If the timezone of the input date is specified as-0000
(indicating it is in UTC but contains no information about the source timezone), thendatetime
will be a naivedatetime
. If a specific timezone offset is found (including+0000
), thendatetime
will contain an awaredatetime
that usesdatetime.timezone
to record the timezone offset.
Значення
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
, що кодує адреси та групи, знайдені у значенні заголовка. Адреси, які не є частиною групи, представлені в цьому списку як одноадресніГрупи
, у якихdisplay_name
має значенняNone
.
- addresses¶
Кортеж об’єктів
Address
, що кодує всі окремі адреси зі значення заголовка. Якщо значення заголовка містить будь-які групи, окремі адреси з групи включаються до списку в тому місці, де група зустрічається у значенні (тобто список адрес «зрівнюється» в одновимірний список).
The
decoded
value of the header will have all encoded words decoded to unicode.idna
encoded domain names are also decoded to unicode. Thedecoded
value is set by joining thestr
value of the elements of thegroups
attribute with', '
.Для встановлення значення заголовка адреси можна використовувати список об’єктів
Address
і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)¶
This is the factory used by
EmailPolicy
by default.HeaderRegistry
builds the class used to create a header instance dynamically, using base_class and a specialized class retrieved from a registry that it holds. When a given header name does not appear in the registry, the class specified by default_class is used as the specialized class. When use_default_map isTrue
(the default), the standard mapping of header names to classes is copied in to the registry during initialization. base_class is always the last class in the generated class’s__bases__
list.Відображення за замовчуванням:
- тема:
UniqueUnstructuredHeader
- дата:
UniqueDateHeader
- дата повторного відправлення:
DateHeader
- дата виходу:
UniqueDateHeader
- відправник:
UniqueSingleAddressHeader
- resent-sender:
SingleAddressHeader
- до:
UniqueAddressHeader
- обурюватися:
AddressHeader
- cc:
UniqueAddressHeader
- resent-cc:
AddressHeader
- прихована копія:
UniqueAddressHeader
- resent-bcc:
AddressHeader
- від:
UniqueAddressHeader
- обурюватися-від:
AddressHeader
- відповідати на:
UniqueAddressHeader
- мім-версія:
MIMEVersionHeader
- тип вмісту:
ContentTypeHeader
- зміст-диспозиція:
ContentDispositionHeader
- кодування передачі вмісту:
ContentTransferEncodingHeader
- ідентифікатор повідомлення:
MessageIDHeader
HeaderRegistry
має такі методи:- map_to_type(self, name, cls)¶
ім’я — це ім’я заголовка, який буде зіставлено. У реєстрі його буде перетворено на нижній регістр. 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
, викличе помилку. Дозволяються символи Юнікоду, які будуть закодовані властивостями під час серіалізації. Однак, згідно з RFC, Юнікод не дозволений у частині імені користувача адреси.- display_name¶
Частина відображуваної назви адреси, якщо така є, без лапок. Якщо адреса не має відображуваного імені, цей атрибут буде порожнім рядком.
- 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];
Для зручності обробки списків адрес, які складаються з суміші груп і окремих адрес,
Група
також може використовуватися для представлення окремих адрес, які не є частиною групи, встановивши display_name наNone
і надання списку однієї адреси як адрес.- display_name¶
display_name
групи. Якщо значенняNone
і вадресах
є точно однаАдреса
, тодіГрупа
представляє одну адресу, яка не входить до групи.
Виноски