email.policy: ポリシーオブジェクト

Added in version 3.3.

ソースコード: Lib/email/policy.py


email パッケージの主な目的は、メールや MIME に関する各種 RFC に従ってメールメッセージを扱うことです。 しかし、メールの一般的な形式はメール以外の用途でも使われています。 この形式は、名前、コロン、値からなるヘッダーフィールドを並べたブロックと、その後に続く空行、任意の「本文」で構成されます。 メール以外の用途には、主要なメールの RFC にほぼ準拠するものもあれば、そうでないものもあります。 メールを扱う場合でも、RFC への厳密な準拠を避けたいことがあります。 例えば、規格に従わないメールサーバーとやり取りするメールを生成する場合や、利用したい拡張機能を規格に反する方法で実装しているサーバーとやり取りする場合です。

これらのばらばらな用途に対応するためPolicyオブジェクトはEメールパッケージに対して柔軟性を提供します。

Policy オブジェクトは、email パッケージの各部の動作を制御する属性とメソッドをまとめたものです。 email パッケージの各種クラスやメソッドに Policy インスタンスを渡すことで、デフォルトの動作を変更できます。 設定できる値とそのデフォルト値を以下で説明します。

email パッケージの各クラスにはデフォルトのポリシーがあります。 parser のすべてのクラスと関連する便利な関数、および Message クラスでは、Compat32 ポリシーの定義済みインスタンス compat32 が使われます。 このポリシーは Python 3.3 より前の email パッケージと完全な後方互換性を提供します (場合によってはバグとの互換性も含みます)。

EmailMessage のキーワード引数 policy のデフォルトは、EmailPolicy ポリシーの定義済みインスタンス default です。

Message または EmailMessage オブジェクトには、作成時にポリシーが設定されます。 parser でメッセージを作成する場合は、パーザに渡したポリシーがそのメッセージに使われます。 プログラムでメッセージを作成する場合は、作成時にポリシーを指定できます。 メッセージを generator に渡すと、デフォルトではメッセージのポリシーが使われますが、ジェネレータに特定のポリシーを渡してメッセージオブジェクトに格納されたポリシーの代わりに使うこともできます。

email.parser のクラスとパーザ用の便利な関数のキーワード引数 policy のデフォルト値は、将来の Python バージョンで 変更される予定です。 このため parser モジュールで説明するクラスや関数を呼び出すときは、使用するポリシーを常に明示的に指定してください。

このドキュメントの前半では、compat32 を含むすべてのポリシーオブジェクトに共通の機能を定義する 抽象基底クラス、Policy の機能を説明します。 これには email パッケージが内部で呼び出すフックメソッドも含まれ、独自のポリシーでオーバーライドすると動作を変更できます。 後半では具象クラス EmailPolicy と Compat32 を説明します。 これらはそれぞれ、標準の動作を提供するフックと、後方互換の動作や機能を提供するフックを実装します。

Policy インスタンスはイミュータブルですが、複製できます。 クラスのコンストラクタと同じキーワード引数を受け取り、元のインスタンスをコピーして指定された属性の値を変更した新しい Policy インスタンスを返します。

例えば次のコードは、ディスク上のファイルから電子メールメッセージを読み込み、Unix システムの sendmail プログラムに渡します:

>>> 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()

ここでは、sendmail の stdin に渡すバイナリ文字列を作成するときに、RFC に従った改行文字を使うよう BytesGenerator に指定しています。 デフォルトのポリシーでは改行文字に \n を使います。

email パッケージの一部のメソッドはキーワード引数 policy を受け取り、そのメソッドで使うポリシーを変更できます。 例えば次のコードは、前の例の msg オブジェクトの as_bytes() メソッドを使い、実行しているプラットフォーム固有の改行文字でメッセージをファイルに書き込みます。

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

Policyオブジェクトは加算オペレータを使用して組み合わせることも可能で、それらのオブジェクトの非デフォルト値を組み合わせた設定を持つPolicyオブジェクトを生成します:

>>> 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)

すべてのポリシークラスの 抽象基底クラス です。 いくつかの単純なメソッドのデフォルト実装に加え、イミュータブルにする仕組み、clone() メソッド、コンストラクタの動作を実装しています。

ポリシークラスのコンストラクタには、さまざまなキーワード引数を渡せます。 指定できる引数は、このクラスと具象クラスにあるメソッド以外のすべてのプロパティです。 コンストラクタに値を指定すると、対応する属性のデフォルト値が置き換えられます。

このクラスは以下のプロパティを定義しているため、どのポリシークラスのコンストラクタでもこれらの値を指定できます:

max_line_length

行の終端文字を数に含まない、シリアライズした出力の任意の行の最大長。デフォルトは RFC 5322 に従い78となっています。値が 0 または None の場合は行の折り返しを全くしないべきであるということを示します。

linesep

シリアライズした出力の行末に使う文字列です。 RFC では \r\n が必要ですが、Python が内部で使う改行規則に合わせ、デフォルトは \n です。

cte_type

使用可能な、または使用が必要な Content Transfer Encoding の種類を制御します。 指定できる値は次のとおりです:

7bit

すべてのデータを「7 ビットクリーン」(ASCII のみ) にする必要があります。 このため必要に応じて quoted-printable または base64 でデータをエンコードします。

8bit

データを 7 ビットクリーンにする必要はありません。 ヘッダ内のデータは依然として ASCII のみに制限されるためエンコードされますが (例外については以下の fold_binary() と utf8 を参照)、本体の各部分では 8bit の CTE を使えます。

文字列はバイナリデータを含められないため、cte_type の値 8bit は BytesGenerator でのみ機能し、Generator では機能しません。 Generator が cte_type=8bit を指定したポリシーで動作する場合は、cte_type が 7bit であるかのように動作します。

raise_on_defect

True の場合、見つかった不具合はすべてエラーとして送出されます。 False (デフォルト) の場合、不具合は register_defect() メソッドに渡されます。

mangle_from_

True の場合、本体内で "From " で始まる行は先頭に > を付けてエスケープされます。 このパラメータはジェネレータがメッセージをシリアライズするときに使います。 デフォルトは False です。

Added in version 3.5.

message_factory

新しい空のメッセージオブジェクトを作成するファクトリ関数です。 パーザがメッセージを組み立てるときに使います。 デフォルトは None で、この場合は Message を使います。

Added in version 3.6.

verify_generated_headers

True (デフォルト) の場合、折り返しや区切りが不適切で、複数のヘッダとして解析されたり隣接するデータと結合されたりするヘッダを書き込む代わりに、ジェネレータは HeaderWriteError を送出します。 このようなヘッダは独自のヘッダクラスや email モジュールのバグによって生成される可能性があります。

セキュリティ機能であるため、Compat32 ポリシーでもデフォルトは True です。 安全ではありませんが後方互換の動作にするには、明示的に False に設定しなければなりません。

Added in version 3.13.

次の Policy メソッドは、email ライブラリを使うコードから呼び出して、設定を変更したポリシーのインスタンスを作成するためのものです:

clone(**kw)

現在のインスタンスと同じ属性値を持つ新しい Policy インスタンスを返します。 ただし、キーワード引数で指定された属性は新しい値になります。

残りの Policy メソッドは email パッケージのコードから呼び出すもので、email パッケージを使うアプリケーションから呼び出すためのものではありません。 独自のポリシーはこれらのメソッドをすべて実装しなければなりません。

handle_defect(obj, defect)

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

デフォルトの実装は 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 MessageDefect.

デフォルトの実装は、obj の defects 属性の append メソッドを呼び出します。 email パッケージが handle_defect を呼び出すとき、通常 obj には append メソッドを持つ defects 属性があります。 email パッケージとともに使う独自のオブジェクト型 (例えば独自の Message オブジェクト) もこの属性を提供する必要があります。 そうしないと、解析したメッセージの不具合が予期しないエラーを引き起こします。

header_max_count(name)

name というヘッダに許される最大の数を返します。

EmailMessage または Message オブジェクトにヘッダを追加するときに呼び出されます。 返り値が 0 でも None でもなく、name という名前のヘッダがすでに返り値以上の個数存在する場合、ValueError が送出されます。

Message.__setitem__ のデフォルトの動作はヘッダのリストへの追加であるため、気付かないうちにヘッダを重複させてしまいがちです。 このメソッドを使うと、特定のヘッダについて、プログラムから Message に追加できる個数を制限できます。 (パーザはこの制限に従わず、解析対象のメッセージにあるヘッダをその個数のまま忠実に生成します。)

デフォルトの実装は全てのヘッダ名に None を返します。

header_source_parse(sourcelines)

email パッケージは文字列のリストを渡してこのメソッドを呼び出します。 各文字列は解析対象の入力にあった改行文字で終わります。 最初の行にはヘッダのフィールド名と区切り文字が含まれます。 入力中の空白文字はすべて保持されます。 このメソッドは、解析したヘッダを表すために Message に格納する (name, value) タプルを返す必要があります。

既存の email パッケージのポリシーとの互換性を維持するには、name は大文字・小文字を保持した名前 (区切り文字「:」より前のすべての文字) にしてください。 value は折り返しを解除した値 (すべての改行文字を削除し、空白文字は保持したもの) から先頭の空白文字を取り除いたものにしてください。

sourcelines はサロゲートエスケープされたバイナリーデータを持つことがあります。

デフォルトの実装はありません。

header_store_parse(name, value)

アプリケーションプログラムが Message をプログラムで変更する場合 (パーザによる作成とは異なります)、email パッケージはそのプログラムが指定した名前と値を渡してこのメソッドを呼び出します。 このメソッドは、ヘッダを表すために Message に格納する (name, value) タプルを返す必要があります。

既存の email パッケージのポリシーとの互換性を維持するには、name と value は文字列または文字列のサブクラスで、渡された引数の内容を変更しないものにしてください。

デフォルトの実装はありません。

header_fetch_parse(name, value)

アプリケーションプログラムがヘッダを要求すると、email パッケージは現在 Message に格納されている name と value を渡してこのメソッドを呼び出します。 このメソッドの返り値が、取得するヘッダの値としてアプリケーションに渡されます。 Message には同名のヘッダが複数格納されていることがあります。 このメソッドには、アプリケーションに返す対象のヘッダの名前と値が渡されます。

value はサロゲートエスケープされたバイナリーデータを持つことがあります。このメソッドの返り値にはサロゲートエスケープされたバイナリーデータはありません。

デフォルトの実装はありません。

fold(name, value)

email パッケージは、対象のヘッダについて現在 Message に格納されている name と value を渡してこのメソッドを呼び出します。 このメソッドは name と value を組み合わせ、適切な位置に linesep の文字を挿入して、ポリシーの設定に従って正しく「折り返した」ヘッダを表す文字列を返す必要があります。 電子メールのヘッダの折り返し規則については RFC 5322 を参照してください。

value はサロゲートエスケープされたバイナリーデータを持つことがあります。このメソッドが返す文字列にはサロゲートエスケープされたバイナリーデータはありません。

fold_binary(name, value)

返り値が文字列でなく bytes オブジェクトである点を除けば、fold() と同じです。

value はサロゲートエスケープされたバイナリデータを持つことがあります。これらは返されたbytesオブジェクト内でバイナリデータに変換されることがあります。

class email.policy.EmailPolicy(**kw)

この具象 Policy は、現行の電子メールの RFC に完全に準拠することを意図した動作を提供します。 対象には RFC 5322、RFC 2047、現行の MIME の RFC などが含まれます。

このポリシーはヘッダの解析と折り返しに新しいアルゴリズムを導入します。 ヘッダは単純な文字列ではなく、フィールドの種類に応じた属性を持つ str のサブクラスになります。 解析と折り返しのアルゴリズムは RFC 2047 と RFC 5322 を完全に実装しています。

message_factory 属性のデフォルト値は EmailMessage です。

すべてのポリシーに適用される、上記の設定可能な属性に加え、このポリシーには以下の属性があります:

Added in version 3.6: [1]

utf8

False の場合は RFC 5322 に従い、ヘッダ内の非 ASCII 文字を RFC 2047 の "encoded words" としてエンコードします。 True の場合は RFC 6532 に従い、ヘッダに utf-8 エンコーディングを使います。 この形式のメッセージは SMTPUTF8 拡張 (RFC 6531) をサポートする SMTP サーバーに渡せます。

False の場合、RFC 2047 で encoded words が許可されていない位置に非 ASCII 文字を含むヘッダがあると、ジェネレータは HeaderWriteError を送出します。 特に、Address で作成できる、非 ASCII 文字を含むメールボックス ("addr-spec") がこれに該当します。 utf8=False で非 ASCII のドメイン名を持つメールボックスを使うには、まずサードパーティーの idna や uts46 モジュール、または encodings.idna でドメイン名をエンコードしてください。 utf8=False の場合、メールボックスに非 ASCII のユーザー名 ("local-part") は使えません。

バージョン 3.15 で変更: HeaderWriteError が送出されることがあります。 (以前のバージョンでは、特に addr-spec などの一部の位置で RFC 2047 が誤って適用されていました。)

refold_source

Message オブジェクト内のヘッダの値が、プログラムによる設定ではなく parser による解析で得られた場合、この属性はメッセージをシリアライズされた形式に戻す際にジェネレータがその値を折り返し直すかどうかを示します。 指定できる値は次のとおりです:

none

入力から得られたすべての値について、元の折り返しを使います。

long

入力から得られた値に max_line_length を超える長さの行がある場合、その値を折り返し直します。

all

すべての値を折り返し直します。

デフォルトは long です。

header_factory

ヘッダのフィールド名 name と折り返しを解除したフィールド値 value の 2 つの引数を取り、そのヘッダを表す文字列のサブクラスを返す呼び出し可能オブジェクトです。 デフォルトの header_factory (headerregistry を参照) は、RFC 5322 の各種アドレス・日付ヘッダフィールドと、主要な MIME ヘッダフィールドに応じた解析をサポートしています。 今後、さらに独自の解析への対応が追加される予定です。

content_manager

少なくとも get_content と set_content の 2 つのメソッドを持つオブジェクトです。 EmailMessage オブジェクトの get_content() または set_content() メソッドが呼び出されると、このオブジェクトの対応するメソッドを呼び出します。 その際、最初の引数としてメッセージオブジェクトを渡し、元の呼び出しで渡された引数やキーワード引数を追加の引数として渡します。 デフォルトでは content_manager は raw_data_manager に設定されています。

Added in version 3.4.

このクラスは Policy の抽象メソッドの具象実装を提供します:

header_max_count(name)

指定された名前のヘッダを表す専用クラスの max_count 属性の値を返します。

header_source_parse(sourcelines)

名前は「:」より前のすべての文字として解析され、そのまま返されます。 値は、最初の行の残りから先頭の空白文字を取り除き、その後のすべての行を連結し、末尾の復帰文字や改行文字を取り除いて求めます。

header_store_parse(name, value)

名前は変更せずに返します。 入力値に name 属性があり、大文字・小文字を区別せずに name と一致する場合、値はそのまま返します。 それ以外の場合は name と value を header_factory に渡し、得られたヘッダオブジェクトを値として返します。 この場合、入力値に CR または LF 文字が含まれていると ValueError を送出します。

header_fetch_parse(name, value)

値に name 属性がある場合は、そのまま返します。 それ以外の場合は、name と、CR や LF 文字を取り除いた value を header_factory に渡し、得られたヘッダオブジェクトを返します。 サロゲートエスケープされたバイトは Unicode の不明な文字を表す記号に置き換えられます。

fold(name, value)

ヘッダの折り返しはポリシーの refold_source 設定で制御します。 name 属性を持たない値だけを「入力から得られた値」とみなします (name 属性がある場合は何らかのヘッダオブジェクトです)。 ポリシーに従って入力から得られた値を折り返し直す必要がある場合は、name と、CR や LF 文字を取り除いた value を header_factory に渡し、ヘッダオブジェクトに変換します。 ヘッダオブジェクトの折り返しは、現在のポリシーを渡してその fold メソッドを呼び出すことで行います。

入力から得られた値は splitlines() で行に分割されます。 折り返し直さない場合は、ポリシーの linesep を使って行を再び連結し、返します。 ただし非 ASCII のバイナリデータを含む行は例外です。 この場合は refold_source の設定にかかわらず値を折り返し直し、unknown-8bit 文字セットを使ってバイナリデータを CTE エンコードします。

fold_binary(name, value)

返り値が bytes である点を除いて、cte_type が 7bit の場合は fold() と同じです。

If cte_type is 8bit, non-ASCII binary data is converted back into bytes. Headers with binary data are not refolded, regardless of the refold_source setting, since there is no way to know whether the binary data consists of single byte characters or multibyte characters.

以下の EmailPolicy インスタンスは、特定の用途に適したデフォルト値を提供します。 今後、各用途に関係する RFC にさらに厳密に準拠するよう、これらのインスタンス (特に HTTP インスタンス) の動作が調整される可能性があります。

email.policy.default

デフォルト値を変更していない EmailPolicy のインスタンスです。このポリシーの行末は、 RFC で正しい \r\n ではなく Python の標準の \n です。

email.policy.SMTP

電子メールの RFC に準拠してメッセージをシリアライズするのに適しています。 default と同様ですが、linesep は RFC に準拠した \r\n に設定されています。

email.policy.SMTPUTF8

utf8 が True である点を除き、SMTP と同じです。 ヘッダに encoded words を使わず、メッセージの保存先にシリアライズするのに便利です。 SMTP 送信では、送信者または受信者のアドレスに非 ASCII 文字が含まれる場合だけ使ってください (smtplib.SMTP.send_message() メソッドはこれを自動的に処理します)。

email.policy.HTTP

HTTP 通信で使うヘッダのシリアライズに適しています。 SMTP と同様ですが、max_line_length は None (無制限) に設定されています。

email.policy.strict

便宜的に用意されたインスタンスです。 raise_on_defect が True に設定されている点を除き、default と同じです。 次のように書くと、任意のポリシーを厳格にできます。

somepolicy + policy.strict

これらの EmailPolicy では、email パッケージの実際の API は Python 3.2 の API から以下のように変わります:

  • Message にヘッダを設定すると、そのヘッダが解析されてヘッダオブジェクトが作成されます。

  • Message からヘッダの値を取得すると、そのヘッダが解析されてヘッダオブジェクトが作成され、返されます。

  • すべてのヘッダオブジェクトと、ポリシー設定によって折り返し直されるヘッダには、RFC の折り返しアルゴリズムを完全に実装したアルゴリズムが使われます。 このアルゴリズムは encoded words が必要な位置と許可される位置も判断します。

アプリケーション側から見ると、EmailMessage から取得するヘッダはすべて追加の属性を持つヘッダオブジェクトになり、その文字列の値は完全にデコードされたヘッダの値になります。 同様に、文字列を使ってヘッダに新しい値を代入したり、新しいヘッダを作成したりできます。 ポリシーがその文字列を RFC に従う正しいエンコード形式に変換します。

ヘッダオブジェクトとその属性は headerregistry で述べられています。

class email.policy.Compat32(**kw)

この具象 Policy は後方互換性のためのポリシーです。 Python 3.2 の email パッケージの動作を再現します。 policy モジュールには、このクラスのインスタンス compat32 も定義されており、デフォルトのポリシーとして使われます。 このため email パッケージはデフォルトでは Python 3.2 との互換性を維持するように動作します。

以下の属性は Policy デフォルトとは異なる値を持ちます:

mangle_from_

デフォルトは True です。

このクラスは Policy の抽象メソッドの具象実装を提供します:

header_source_parse(sourcelines)

名前は「:」より前のすべての文字として解析され、そのまま返されます。 値は、最初の行の残りから先頭の空白文字を取り除き、その後のすべての行を連結し、末尾の復帰文字や改行文字を取り除いて求めます。

header_store_parse(name, value)

名前と値は変更されずに返されます。

header_fetch_parse(name, value)

値にバイナリデータが含まれる場合、unknown-8bit 文字セットを使って Header オブジェクトに変換します。 それ以外の場合はそのまま返します。

fold(name, value)

ヘッダは Header の折り返しアルゴリズムで折り返します。 このアルゴリズムは値に含まれる既存の改行を保持し、各行を max_line_length に収まるように折り返します。 非 ASCII のバイナリデータは unknown-8bit 文字セットを使って CTE エンコードされます。

fold_binary(name, value)

ヘッダは Header の折り返しアルゴリズムで折り返します。 このアルゴリズムは値に含まれる既存の改行を保持し、各行を max_line_length に収まるように折り返します。 cte_type が 7bit の場合、非 ASCII のバイナリデータは unknown-8bit 文字セットを使って CTE エンコードされます。 それ以外の場合は入力のヘッダをそのまま使い、既存の改行と、含まれていればバイナリデータ (RFC では無効です) を保持します。

email.policy.compat32

Compat32 のインスタンスで、Python 3.2 の email パッケージの挙動との後方互換性を提供します。

注釈

compat32 ポリシーは EmailMessage オブジェクトのポリシーとして使わないでください。 compat32 ポリシーで作成されたメッセージをシリアライズする場合だけ使ってください。

脚注