# `email.policy`: Policy Objects

Нове в версії 3.3.

Вихідний код: Lib/email/policy.py

Пакунок `email` головним чином зосереджується на обробці повідомлень електронної пошти, як описано в різних RFC електронної пошти та MIME. Однак загальний формат повідомлень електронної пошти (блок полів заголовка, кожне з яких складається з назви, за якою йде двокрапка, за якою йде значення, весь блок, після якого йде порожній рядок і довільний «тіло»), — це формат, який знайшов утиліта за межами сфери електронної пошти. Деякі з цих способів використання досить точно відповідають основним RFC електронної пошти, інші – ні. Навіть під час роботи з електронною поштою бувають випадки, коли бажано порушити сувору відповідність RFC, наприклад, створювати електронні листи, які взаємодіють із серверами електронної пошти, які самі по собі не дотримуються стандартів, або які реалізують розширення, які ви хочете використовувати, у спосіб, який порушує стандарти.

Об’єкти політики надають пакету електронної пошти гнучкість для обробки всіх цих різнорідних випадків використання.

Об’єкт `Policy` інкапсулює набір атрибутів і методів, які контролюють поведінку різних компонентів пакета електронної пошти під час використання. Екземпляри `Policy` можна передати різним класам і методам у пакеті електронної пошти, щоб змінити типову поведінку. Нижче описано встановлені значення та їх значення за замовчуванням.

Існує політика за замовчуванням, яка використовується всіма класами в пакеті електронної пошти. Для всіх класів `parser` і відповідних функцій зручності, а також для класу `Message`, це політика `Compat32` через відповідну політику попередньо визначений екземпляр `compat32`. Ця політика забезпечує повну зворотну сумісність (у деяких випадках, включаючи сумісність із помилками) із версією пакета електронної пошти до Python3.3.

Це значення за умовчанням для ключового слова policy для `EmailMessage` є політикою `EmailPolicy` через її попередньо визначений екземпляр `default`.

Коли створюється об’єкт `Message` або `EmailMessage`, він отримує політику. Якщо повідомлення створено `parser`, політика, передана аналізатору, буде політикою, яка використовується у створеному ним повідомленні. Якщо повідомлення створюється програмою, то під час його створення можна вказати політику. Коли повідомлення передається до `generator`, генератор використовує політику з повідомлення за замовчуванням, але ви також можете передати певну політику генератору, яка замінить політику, збережену в об’єкті повідомлення.

Значення за замовчуванням для ключового слова policy для класів `email.parser` і зручних функцій синтаксичного аналізатора буде змінено в наступній версії Python. Тому ви повинні завжди чітко вказувати, яку політику ви хочете використовувати під час виклику будь-якого з класів і функцій, описаних у модулі `parser`.

Перша частина цієї документації охоплює функції `Policy`, abstract base class, який визначає функції, спільні для всіх об’єктів політики, включаючи `compat32`. Це включає в себе певні методи підключення, які викликаються внутрішньо пакетом електронної пошти, які спеціальна політика може замінити, щоб отримати іншу поведінку. Друга частина описує конкретні класи `EmailPolicy` і `Compat32`, які реалізують хуки, які забезпечують стандартну поведінку та зворотну сумісність і функції відповідно.

Екземпляри `Policy` незмінні, але їх можна клонувати, приймаючи ті самі аргументи ключового слова, що й конструктор класу, і повертаючи новий екземпляр `Policy`, який є копією оригіналу, але зі зміненими значеннями вказаних атрибутів .

Як приклад, наступний код можна використати для читання повідомлення електронної пошти з файлу на диску та передачі його системній програмі `sendmail` в системі Unix:

    >>> from email import message_from_binary_file
    >>> from email.generator import BytesGenerator
    >>> from email import policy
    >>> from subprocess import Popen, PIPE
    >>> with open('mymsg.txt', 'rb') as f:
    ...     msg = message_from_binary_file(f, policy=policy.default)
    >>> p = Popen(['sendmail', msg['To'].addresses[0]], stdin=PIPE)
    >>> g = BytesGenerator(p.stdin, policy=msg.policy.clone(linesep='\r\n'))
    >>> g.flatten(msg)
    >>> p.stdin.close()
    >>> rc = p.wait()

Тут ми повідомляємо `BytesGenerator` використовувати правильні символи роздільників рядків RFC під час створення двійкового рядка для передачі в `stdin` `sendmail`, де політика за замовчуванням використовуватиме `\n` роздільники рядків.

Деякі методи пакетів електронної пошти приймають аргумент ключового слова policy, що дозволяє перевизначати політику для цього методу. Наприклад, у наступному коді використовується метод `as_bytes()` об’єкта msg із попереднього прикладу та записує повідомлення у файл, використовуючи рідні розділювачі рядків для платформи, на якій воно біжить:

    >>> import os
    >>> with open('converted.txt', 'wb') as f:
    ...     f.write(msg.as_bytes(policy=msg.policy.clone(linesep=os.linesep)))
    17

Об’єкти політики також можна комбінувати за допомогою оператора додавання, утворюючи об’єкт політики, параметри якого є комбінацією нестандартних значень сумованих об’єктів:

    >>> compat_SMTP = policy.compat32.clone(linesep='\r\n')
    >>> compat_strict = policy.compat32.clone(raise_on_defect=True)
    >>> compat_strict_SMTP = compat_SMTP + compat_strict

Ця операція не є комутативною; тобто порядок, у якому додаються об’єкти, має значення. Проілюструвати:

    >>> policy100 = policy.compat32.clone(max_line_length=100)
    >>> policy80 = policy.compat32.clone(max_line_length=80)
    >>> apolicy = policy100 + policy80
    >>> apolicy.max_line_length
    80
    >>> apolicy = policy80 + policy100
    >>> apolicy.max_line_length
    100

class email.policy.Policy(**kw)

  Це abstract base class для всіх класів політики. Він забезпечує реалізацію за замовчуванням для кількох тривіальних методів, а також реалізацію властивості незмінності, метод `clone()` і семантику конструктора.

  Конструктору класу політики можна передати різні ключові аргументи. Аргументами, які можна вказати, є будь-які неметодні властивості цього класу, а також будь-які додаткові неметодні властивості конкретного класу. Значення, указане в конструкторі, замінить значення за замовчуванням для відповідного атрибута.

  Цей клас визначає наступні властивості, і, отже, значення для наступного можна передати в конструктор будь-якого класу політики:

  max_line_length

    Максимальна довжина будь-якого рядка в серіалізованому виведенні, не враховуючи символ(и) кінця рядка. За замовчуванням 78 відповідно до RFC 5322. Значення `0` або `None` вказує на те, що перенесення рядків не потрібно виконувати взагалі.

  linesep

    Рядок, який буде використовуватися для завершення рядків у серіалізованому виведенні. Типовим є `\n`, оскільки це внутрішня дисципліна кінця рядка, яка використовується Python, хоча `\r\n` вимагається RFC.

  cte_type

    Керує типом кодувань передачі вмісту, які можуть або повинні використовуватися. Можливі значення:

    `7 біт` | усі дані мають бути «7-бітними чистими» (лише ASCII). Це означає, що там, де це необхідно, дані будуть закодовані з використанням кодування для друку в цитатах або кодування base64.
    `8 біт` | дані не мають обмежень бути чистими 7 біт. Дані в заголовках, як і раніше, повинні бути лише ASCII, тому вони будуть закодовані (див. `fold_binary()` і `utf8` нижче для винятків), але частини тіла можуть використовувати `8bit` CTE.

    Значення `cte_type` `8bit` працює лише з `BytesGenerator`, а не `Generator`, оскільки рядки не можуть містити двійкові дані. Якщо `генератор` працює відповідно до політики, яка визначає `cte_type=8bit`, він діятиме так, ніби `cte_type` має значення `7bit`.

  raise_on_defect

    Якщо `True`, будь-які виявлені дефекти визначатимуться як помилки. Якщо `False` (за замовчуванням), дефекти будуть передані в метод `register_defect()`.

  mangle_from_

    Якщо `True`, рядки, що починаються з «From « у тілі, екрануються шляхом розміщення `>` перед ними. Цей параметр використовується, коли повідомлення серіалізується генератором. Типове значення: `False`.

    Нове в версії 3.5.

  message_factory

    Фабрична функція для створення нового порожнього об’єкта повідомлення. Використовується аналізатором під час створення повідомлень. За замовчуванням `None`, у цьому випадку використовується `Message`.

    Нове в версії 3.6.

  verify_generated_headers

    If `True` (the default), the generator will raise `HeaderWriteError` instead of writing a header that is improperly folded or delimited, such that it would be parsed as multiple headers or joined with adjacent data. Such headers can be generated by custom header classes or bugs in the `email` module.

    As it’s a security feature, this defaults to `True` even in the `Compat32` policy. For backwards compatible, but unsafe, behavior, it must be set to `False` explicitly.

    Нове в версії 3.11.10.

  Наступний метод `Policy` призначений для виклику за допомогою коду за допомогою бібліотеки електронної пошти для створення екземплярів політики з настроюваними налаштуваннями:

  clone(**kw)

    Повертає новий екземпляр `Policy`, атрибути якого мають ті самі значення, що й поточний екземпляр, за винятком тих випадків, коли ці атрибути отримують нові значення аргументами ключового слова.

  Решта методів `Policy` викликається кодом пакета електронної пошти і не призначена для виклику програмою, яка використовує пакет електронної пошти. Спеціальна політика повинна реалізовувати всі ці методи.

  handle_defect(obj, defect)

    Handle a defect found on obj. When the email package calls this method, defect will always be a subclass of `Defect`.

    Стандартна реалізація перевіряє прапорець `raise_on_defect`. Якщо значення `True`, defect створюється як виняток. Якщо значення `False` (за замовчуванням), obj і defect передаються в `register_defect()`.

  register_defect(obj, defect)

    Register a defect on obj. In the email package, defect will always be a subclass of `Defect`.

    Стандартна реалізація викликає метод `append` атрибута `defects` obj. Коли пакет електронної пошти викликає `handle_defect`, obj зазвичай матиме атрибут `defects`, який має метод `append`. Спеціальні типи об’єктів, які використовуються з пакетом електронної пошти (наприклад, спеціальні об’єкти `Message`), також повинні надавати такий атрибут, інакше дефекти в проаналізованих повідомленнях призведуть до неочікуваних помилок.

  header_max_count(name)

    Повертає максимально дозволену кількість заголовків із назвою ім’я.

    Викликається, коли заголовок додається до об’єкта `EmailMessage` або `Message`. Якщо повернуте значення не є `0` або `None`, і вже існує кількість заголовків з іменем name, більшим або рівним поверненому значенню, виникає `ValueError` .

    Оскільки за замовчуванням `Message.__setitem__` додає значення до списку заголовків, легко створити дублікати заголовків, не усвідомлюючи цього. Цей метод дозволяє обмежити певні заголовки в кількості екземплярів цього заголовка, які можна додати до `повідомлення` програмним шляхом. (Обмеження не дотримується синтаксичним аналізатором, який сумлінно створить стільки заголовків, скільки існує в повідомленні, що аналізується.)

    Реалізація за замовчуванням повертає `None` для всіх імен заголовків.

  header_source_parse(sourcelines)

    Пакет електронної пошти викликає цей метод зі списком рядків, кожен рядок закінчується символами розділення рядків, знайденими в джерелі, що аналізується. Перший рядок містить назву заголовка поля та роздільник. Усі пробіли в джерелі збережено. Метод має повертати кортеж `(name, value)`, який має зберігатися в `Message` для представлення аналізованого заголовка.

    Якщо реалізація бажає зберегти сумісність із існуючими політиками пакетів електронної пошти, ім’я має бути ім’ям із збереженням регістру (усі символи до роздільника «`:`), тоді як значення має бути розгорнутим значенням (усі символи-роздільники рядків видалено, але пробіли збережено без змін), видалено пробіли на початку.

    вихідні лінії можуть містити сурогатні двійкові дані.

    Реалізації за замовчуванням немає

  header_store_parse(name, value)

    Пакет електронної пошти викликає цей метод із назвою та значенням, наданими прикладною програмою, коли прикладна програма програмно змінює `повідомлення` (на відміну від `повідомлення`, створеного аналізатором). Метод має повертати кортеж `(name, value)`, який має зберігатися в `Message` для представлення заголовка.

    Якщо реалізація бажає зберегти сумісність із існуючими політиками пакетів електронної пошти, ім’я та значення мають бути рядками або підкласами рядків, які не змінюють вміст переданих аргументів.

    Реалізації за замовчуванням немає

  header_fetch_parse(name, value)

    Пакет електронної пошти викликає цей метод із ім’ям і значенням, які наразі зберігаються в `Message`, коли прикладна програма запитує цей заголовок, і те, що метод повертає, передається назад до програми як значення заголовка, що витягується. Зауважте, що в `Повідомленні` може бути більше одного заголовка з однаковою назвою; методу передається конкретне ім’я та значення заголовка, призначеного для повернення до програми.

    значення може містити сурогатні екрановані двійкові дані. У значенні, яке повертає метод, не повинно бути сурогатних двійкових даних.

    Реалізації за замовчуванням немає

  fold(name, value)

    Пакет електронної пошти викликає цей метод із ім’ям і значенням, які наразі зберігаються в `Повідомленні` для заданого заголовка. Метод має повернути рядок, який представляє цей заголовок, «згорнутий» правильно (відповідно до налаштувань політики), складаючи ім’я з значенням і вставляючи символи `linesep` у відповідних місцях. Перегляньте RFC 5322 для обговорення правил згортання заголовків електронних листів.

    значення може містити сурогатні екрановані двійкові дані. У рядку, який повертає метод, не повинно бути сурогатних двійкових даних.

  fold_binary(name, value)

    Те саме, що `fold()`, за винятком того, що повернуте значення має бути об’єктом bytes, а не рядком.

    значення може містити сурогатні екрановані двійкові дані. Вони можуть бути перетворені назад у двійкові дані у повернутому об’єкті bytes.

class email.policy.EmailPolicy(**kw)

  Ця конкретна `Policy` забезпечує поведінку, яка повністю відповідає поточним RFC електронної пошти. До них належать (але не обмежуються ними) RFC 5322, RFC 2047 і поточні RFC MIME.

  Ця політика додає нові алгоритми аналізу та згортання заголовків. Замість простих рядків, заголовки є підкласами `str` з атрибутами, які залежать від типу поля. Алгоритм аналізу та згортання повністю реалізує RFC 2047 і RFC 5322.

  Значенням за замовчуванням атрибута `message_factory` є `EmailMessage`.

  На додаток до перерахованих вище настроюваних атрибутів, які застосовуються до всіх політик, ця політика додає такі додаткові атрибути:

  Нове в версії 3.6: [1]

  utf8

    Якщо `False`, дотримуйтесь RFC 5322, підтримуючи символи, відмінні від ASCII, у заголовках, кодуючи їх як «закодовані слова». Якщо `True`, слідуйте RFC 6532 і використовуйте `utf-8` кодування для заголовків. Повідомлення, відформатовані таким чином, можуть передаватися на сервери SMTP, які підтримують розширення `SMTPUTF8` (RFC 6531).

  refold_source

    Якщо значення для заголовка в об’єкті `Message` походить від `parser` (на відміну від встановлення програмою), цей атрибут вказує, чи повинен генератор повторно згортати це значення, коли перетворення повідомлення назад у серіалізовану форму. Можливі значення:

    `None` | усі вихідні значення використовують оригінальне згортання
    `довгий` | вихідні значення, які мають будь-який рядок, довший за `max_line_length`, будуть повторно згорнуті
    `все` | усі значення перескладають.

    Типовим є `long`.

  header_factory

    Викликається, що приймає два аргументи, `name` і `value`, де `name` — це ім’я поля заголовка, а `value` — це значення розгорнутого поля заголовка, і повертає підклас рядка, який представляє той заголовок. За замовчуванням надається `header_factory` (див. `headerregistry`), який підтримує спеціальний аналіз для різних типів полів заголовків адреси та дати RFC 5322, а також основних типів полів заголовків MIME. У майбутньому буде додано підтримку додаткового спеціального аналізу.

  content_manager

    Об’єкт із принаймні двома методами: get_content і set_content. Коли викликається метод `get_content()` або `set_content()` об’єкта `EmailMessage`, він викликає відповідний метод цього об’єкта, передаючи йому об’єкт повідомлення як його перший аргумент, а також будь-які аргументи або ключові слова, які були передані йому як додаткові аргументи. За умовчанням `content_manager` встановлено на `raw_data_manager`.

    Нове в версії 3.4.

  Клас забезпечує такі конкретні реалізації абстрактних методів `Policy`:

  header_max_count(name)

    Повертає значення атрибута `max_count` спеціалізованого класу, який використовується для представлення заголовка з заданим іменем.

  header_source_parse(sourcelines)

    Ім’я аналізується як усе, аж до «`:`», і повертається без змін. Значення визначається видаленням початкових пробілів із решти першого рядка, з’єднанням усіх наступних рядків разом і видаленням будь-яких завершальних символів повернення каретки або переводу рядка.

  header_store_parse(name, value)

    Ім’я повертається без змін. Якщо вхідне значення має атрибут `name` і воно відповідає name без урахування регістру, значення повертається без змін. В іншому випадку ім’я та значення передаються до `header_factory`, а отриманий об’єкт заголовка повертається як значення. У цьому випадку виникає `ValueError`, якщо вхідне значення містить символи CR або LF.

  header_fetch_parse(name, value)

    Якщо значення має атрибут `name`, воно повертається до незміненого. В іншому випадку ім’я та значення з видаленими будь-якими символами CR або LF передаються до `header_factory`, і повертається отриманий об’єкт заголовка. Будь-які сурогатні екрановані байти перетворюються на гліф невідомих символів Unicode.

  fold(name, value)

    Згортання заголовка контролюється параметром політики `refold_source`. Значення вважається «вихідним значенням» тоді і тільки тоді, коли воно не має атрибута `name` (наявність атрибута `name` означає, що це певний об’єкт заголовка). Якщо вихідне значення потрібно повторно згорнути відповідно до політики, воно перетворюється на об’єкт заголовка шляхом передачі name і value з будь-якими символами CR і LF, видаленими до `header_factory`. Згортання об’єкта заголовка виконується викликом його методу `fold` із поточною політикою.

    Вихідні значення розбиваються на рядки за допомогою `splitlines()`. Якщо значення не потрібно повторно згортати, рядки знову об’єднуються за допомогою `linesep` із політики та повертаються. Винятком є рядки, що містять двійкові дані, відмінні від ASCII. У цьому випадку значення повторно згортається незалежно від параметра `refold_source`, що призводить до того, що двійкові дані кодуються CTE за допомогою набору символів `unknown-8bit`.

  fold_binary(name, value)

    Те саме, що `fold()`, якщо `cte_type` має значення `7bit`, за винятком того, що повертається значення байтів.

    Якщо `cte_type` має значення `8bit`, двійкові дані, відмінні від ASCII, перетворюються назад у байти. Заголовки з двійковими даними не згортаються повторно, незалежно від параметра `refold_header`, оскільки немає способу дізнатися, чи двійкові дані складаються з однобайтових символів чи багатобайтових символів.

Наступні екземпляри `EmailPolicy` забезпечують значення за замовчуванням, придатні для певних доменів програм. Зауважте, що в майбутньому поведінка цих екземплярів (зокрема екземпляра `HTTP`) може бути налаштована для ще більшої відповідності RFC, що стосуються їхніх доменів.

email.policy.default

  Екземпляр `EmailPolicy` з незмінними параметрами за замовчуванням. Ця політика використовує стандартні закінчення рядків Python `\n` замість правильного RFC `\r\n`.

email.policy.SMTP

  Підходить для серіалізації повідомлень відповідно до RFC електронної пошти. Як `default`, але `linesep` має значення `\r\n`, що відповідає RFC.

email.policy.SMTPUTF8

  Те саме, що `SMTP`, за винятком того, що `utf8` має значення `True`. Корисно для серіалізації повідомлень до сховища повідомлень без використання закодованих слів у заголовках. Слід використовувати лише для передачі SMTP, якщо адреси відправника чи одержувача містять символи, відмінні від ASCII (метод `smtplib.SMTP.send_message()` обробляє це автоматично).

email.policy.HTTP

  Підходить для серіалізації заголовків для використання в трафіку HTTP. Подібно до `SMTP`, за винятком того, що `max_line_length` встановлено на `None` (необмежено).

email.policy.strict

  Зручний екземпляр. Те саме, що `default`, за винятком того, що `raise_on_defect` має значення `True`. Це дозволяє зробити будь-яку політику суворою, написавши:

      somepolicy + policy.strict

З усіма цими `EmailPolicies` ефективний API пакета електронної пошти змінюється від API Python 3.2 у такий спосіб:

- Встановлення заголовка в `Message` призводить до аналізу цього заголовка та створення об’єкта заголовка.

- Отримання значення заголовка з `Message` призводить до аналізу цього заголовка та створення та повернення об’єкта заголовка.

- Будь-який об’єкт заголовка або будь-який заголовок, який повторно згортається через параметри політики, згортається за допомогою алгоритму, який повністю реалізує алгоритми згортання RFC, включаючи визначення того, де закодовані слова потрібні та дозволені.

З точки зору програми це означає, що будь-який заголовок, отриманий через `EmailMessage`, є об’єктом заголовка з додатковими атрибутами, рядкове значення якого є повністю розшифрованим значенням заголовка в Unicode. Так само заголовку може бути призначено нове значення або створений новий заголовок за допомогою рядка Юнікод, і політика подбає про перетворення рядка Юнікод у правильну форму, закодовану RFC.

Об’єкти заголовка та їхні атрибути описані в `headerregistry`.

class email.policy.Compat32(**kw)

  Ця конкретна `Policy` є політикою зворотної сумісності. Він повторює поведінку пакета електронної пошти в Python 3.2. Модуль `policy` також визначає екземпляр цього класу, `compat32`, який використовується як політика за замовчуванням. Таким чином, за замовчуванням пакет електронної пошти підтримує сумісність із Python 3.2.

  Наступні атрибути мають значення, які відрізняються від стандартних `Policy`:

  mangle_from_

    Типовим значенням є `True`.

  Клас забезпечує такі конкретні реалізації абстрактних методів `Policy`:

  header_source_parse(sourcelines)

    Ім’я аналізується як усе, аж до «`:`», і повертається без змін. Значення визначається видаленням початкових пробілів із решти першого рядка, з’єднанням усіх наступних рядків разом і видаленням будь-яких завершальних символів повернення каретки або переводу рядка.

  header_store_parse(name, value)

    Ім’я та значення повертаються без змін.

  header_fetch_parse(name, value)

    Якщо значення містить двійкові дані, воно перетворюється на об’єкт `Header` за допомогою кодування `unknown-8bit`. В іншому випадку він повертається без змін.

  fold(name, value)

    Заголовки згортаються за допомогою алгоритму згортання `Header`, який зберігає наявні розриви рядків у значенні та обертає кожен отриманий рядок до `max_line_length`. Двійкові дані, відмінні від ASCII, кодуються CTE за допомогою набору символів `unknown-8bit`.

  fold_binary(name, value)

    Заголовки згортаються за допомогою алгоритму згортання `Header`, який зберігає наявні розриви рядків у значенні та обертає кожен отриманий рядок до `max_line_length`. Якщо `cte_type` дорівнює `7bit`, двійкові дані, що не є ascii, кодуються CTE з використанням набору символів `unknown-8bit`. В іншому випадку використовується вихідний вихідний заголовок із наявними розривами рядків і будь-якими (недійсними RFC) двійковими даними, які він може містити.

email.policy.compat32

  Екземпляр `Compat32`, що забезпечує зворотну сумісність із поведінкою пакета електронної пошти в Python 3.2.

Виноски

[1]

Спочатку додано в 3.3 як попередню функцію.