email.generator: MIME 文書の生成

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


メッセージオブジェクトの構造で表された電子メールメッセージから、フラットな (直列化された) 表現を生成することは、よく行う処理の一つです。 smtplib.SMTP.sendmail() で送信したり、コンソールに表示したりするには、この処理が必要です。 メッセージオブジェクトの構造を受け取り、直列化された表現を作成するのがジェネレータークラスの役割です。

email.parser モジュールと同様に、付属のジェネレーターの機能だけを使う必要はなく、自分で一から実装することもできます。 ただし、付属のジェネレーターはほとんどの電子メールを標準に準拠して生成でき、MIME メッセージも非 MIME メッセージも適切に扱えるはずです。 また、変換を行わない同じ policy を両方に使えば、バイト列の解析と生成が互いに逆の操作になるよう設計されています。 つまり、直列化されたバイトストリームを BytesParser で解析し、BytesGenerator で再生成すると、入力と同じ出力が得られるはずです [1]。 (一方、プログラムで構築した EmailMessage にジェネレーターを使うと、デフォルト値が補われる際に EmailMessage オブジェクトが変更されることがあります。)

Generator クラスを使うと、メッセージをバイナリではなくテキストの直列化表現にフラット化できます。 ただし、Unicode はバイナリデータを直接表現できないため、メッセージを ASCII 文字だけからなる形式に変換する必要があります。 そのために、8 ビットデータをそのまま通せない経路で電子メールを送信するための、標準の電子メール RFC に定められたコンテンツ転送エンコーディングを使います。

SMIME で署名されたメッセージを再現可能な形で処理できるよう、Generator は multipart/signed 型のパートとそのすべてのサブパートで、ヘッダーの折り返しを無効にします。

class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)

flatten() に渡されたメッセージ、または write() に渡された surrogateescape でエンコードされたテキストを、ファイルライクオブジェクト outfp に書き込む BytesGenerator オブジェクトを返します。 outfp は、バイナリデータを受け取る write() メソッドを持つ必要があります。

オプションの mangle_from_ が True の場合、本体中で正確に文字列 "From " から始まる行、つまり行頭の From の後に空白がある行の先頭に > を追加します。 mangle_from_ のデフォルトは、policy の mangle_from_ 設定の値です (compat32 ポリシーでは True、それ以外では False です)。 mangle_from_ は、メッセージを Unix mbox 形式で保存する場合を想定しています (mailbox と WHY THE CONTENT-LENGTH FORMAT IS BAD を参照してください)。

If maxheaderlen is not None, refold any header lines that are longer than maxheaderlen, or if 0, do not rewrap any headers. If maxheaderlen is None (the default), wrap headers and other message lines according to the policy settings.

policy が指定されていれば、そのポリシーでメッセージの生成を制御します。 policy が None (デフォルト) であれば、flatten() に渡された Message または EmailMessage オブジェクトに関連付けられたポリシーを使います。 policy が制御する内容については email.policy を参照してください。

Added in version 3.2.

バージョン 3.3 で変更: キーワード引数 policy が追加されました。

バージョン 3.6 で変更: mangle_from_ と maxheaderlen 引数のデフォルトの動作が、ポリシーに従うようになりました。

flatten(msg, unixfrom=False, linesep=None)

msg を基点とするメッセージオブジェクト構造体の文字表現を出力します。出力先のファイルにはこの BytesGenerator インスタンスが作成されたときに指定されたものが使われます。

policy の cte_type が 8bit (デフォルト) の場合、解析した元のメッセージのうち変更されていないヘッダーを出力へコピーします。 その際、最上位ビットが立っているバイトも元どおりに再現し、非 ASCII の Content-Transfer-Encoding を持つ本文パートではそれを保持します。 cte_type が 7bit の場合は、ASCII 互換の Content-Transfer-Encoding を使い、最上位ビットが立っているバイトを必要に応じて変換します。 つまり、非 ASCII の Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) を持つパートを ASCII 互換の Content-Transfer-Encoding に変換し、ヘッダー中の RFC に反する非 ASCII バイトを MIME の unknown-8bit 文字セットでエンコードして、RFC に準拠させます。

unixfrom が True の場合、最上位のメッセージオブジェクトの最初の RFC 5322 ヘッダーより前に、Unix メールボックス形式で使うエンベロープヘッダーの区切りを出力します (mailbox を参照)。 最上位のオブジェクトにエンベロープヘッダーがなければ、標準的なものを作成します。 デフォルトは False です。 サブパートではエンベロープヘッダーは出力されません。

linesep が None でない場合、フラット化されたメッセージのすべての行を区切る文字として使います。 linesep が None (デフォルト) の場合、policy で指定された値を使います。

clone(fp)

この BytesGenerator インスタンスとまったく同じオプション設定で、新しい outfp を fp とした、独立した複製を返します。

write(s)

s を ASCII コーデックと surrogateescape エラーハンドラーでエンコードし、BytesGenerator のコンストラクタに渡された outfp の write() メソッドに渡します。

EmailMessage には、メッセージオブジェクトを直列化したバイナリ表現を簡単に生成するための as_bytes() と bytes(aMessage) (すなわち __bytes__()) が用意されています。 詳しくは email.message を参照してください。

Because strings cannot represent binary data, the Generator class must convert any binary data in any message it flattens to an ASCII compatible format, by converting them to an ASCII compatible Content-Transfer-Encoding. Using the terminology of the email RFCs, you can think of this as Generator serializing to an I/O stream that is not "8 bit clean". In other words, most applications will want to be using BytesGenerator, and not Generator.

class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)

flatten() に渡されたメッセージ、または write() に渡されたテキストを、ファイルライクオブジェクト outfp に書き込む Generator オブジェクトを返します。 outfp は、文字列データを受け取る write() メソッドを持つ必要があります。

オプションの mangle_from_ が True の場合、本体中で正確に文字列 "From " から始まる行、つまり行頭の From の後に空白がある行の先頭に > を追加します。 mangle_from_ のデフォルトは、policy の mangle_from_ 設定の値です (compat32 ポリシーでは True、それ以外では False です)。 mangle_from_ は、メッセージを Unix mbox 形式で保存する場合を想定しています (mailbox と WHY THE CONTENT-LENGTH FORMAT IS BAD を参照してください)。

If maxheaderlen is not None, refold any header lines that are longer than maxheaderlen, or if 0, do not rewrap any headers. If maxheaderlen is None (the default), wrap headers and other message lines according to the policy settings.

policy が指定されていれば、そのポリシーでメッセージの生成を制御します。 policy が None (デフォルト) であれば、flatten() に渡された Message または EmailMessage オブジェクトに関連付けられたポリシーを使います。 policy が制御する内容については email.policy を参照してください。

バージョン 3.3 で変更: キーワード引数 policy が追加されました。

バージョン 3.6 で変更: mangle_from_ と maxheaderlen 引数のデフォルトの動作が、ポリシーに従うようになりました。

flatten(msg, unixfrom=False, linesep=None)

msg を基点とするメッセージオブジェクト構造体の文字表現を出力します。出力先のファイルにはこの Generator インスタンスが作成されたときに指定されたものが使われます。

policy の cte_type が 8bit の場合、7bit に設定されているものとしてメッセージを生成します。 (文字列では非 ASCII バイトを表せないため、この処理が必要です。) 最上位ビットが立っているバイトは、ASCII 互換の Content-Transfer-Encoding を使って必要に応じて変換します。 つまり、非 ASCII の Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) を持つパートを ASCII 互換の Content-Transfer-Encoding に変換し、ヘッダー中の RFC に反する非 ASCII バイトを MIME の unknown-8bit 文字セットでエンコードして、RFC に準拠させます。

unixfrom が True の場合、最上位のメッセージオブジェクトの最初の RFC 5322 ヘッダーより前に、Unix メールボックス形式で使うエンベロープヘッダーの区切りを出力します (mailbox を参照)。 最上位のオブジェクトにエンベロープヘッダーがなければ、標準的なものを作成します。 デフォルトは False です。 サブパートではエンベロープヘッダーは出力されません。

linesep が None でない場合、フラット化されたメッセージのすべての行を区切る文字として使います。 linesep が None (デフォルト) の場合、policy で指定された値を使います。

バージョン 3.2 で変更: 8bit メッセージ本体の再エンコードがサポートされました。linesep 引数が追加されました。

clone(fp)

この Generator インスタンスとまったく同じオプションで、新しい outfp を fp とした、独立した複製を返します。

write(s)

Generator のコンストラクタに渡された outfp の write() メソッドに s を書き込みます。 これにより、Generator インスタンスを print() 関数で使うために必要な、最小限のファイルライク API を提供します。

EmailMessage には、メッセージオブジェクトの書式化された文字列表現を簡単に生成するための as_string() と str(aMessage) (すなわち __str__()) が用意されています。 詳しくは email.message を参照してください。

email.generator モジュールは派生クラス DecodedGenerator も提供します。 基底クラスの Generator と似ていますが、text 以外のパートは直列化せず、そのパートの情報をテンプレートに埋め込んだ文字列として出力ストリームに表す点が異なります。

class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)

Generator と同様に動作しますが、Generator.flatten() に渡されたメッセージのサブパートについて、メインタイプが text ならデコードしたペイロードを出力します。 メインタイプが text でなければ、パートをそのまま出力する代わりに、その情報を文字列 fmt に埋め込み、結果の文字列を出力します。

fmt への埋め込みには fmt % part_info を使います。 part_info は以下のキーと値からなる辞書です。

  • type -- 非 text 型 subpart の MIME 形式

  • maintype -- 非 text 型 subpart の MIME 主形式 (maintype)

  • subtype -- 非 text 型 subpart の MIME 副形式 (subtype)

  • filename -- 非 text 型 subpart のファイル名

  • description -- 非 text 型 subpart につけられた説明文字列

  • encoding -- 非 text 型 subpart の Content-transfer-encoding

fmt が None の場合、次のデフォルトの fmt を使います。

"[Non-text (%(type)s) part of message omitted, filename %(filename)s]"

Optional mangle_from_ and maxheaderlen are as with the Generator base class.

脚注