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 を参照してください)。maxheaderlen が
Noneでなければ、maxheaderlen より長いヘッダー行を折り返し直します。0の場合は、どのヘッダーも折り返し直しません。 maxheaderlen がNone(デフォルト) の場合は、policy の設定に従ってヘッダーやその他のメッセージの行を折り返します。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 を参照してください。
文字列ではバイナリデータを表せないため、Generator クラスはメッセージを平坦化する際、
その中のバイナリデータを ASCII と互換性のある Content-Transfer-Encoding を使って ASCII と互換性のある形式に変換する必要があります。
電子メールの RFC の用語を使うと、Generator は「8 bit clean」でない I/O ストリームへ直列化すると考えられます。
つまり、ほとんどのアプリケーションでは Generator よりも BytesGenerator を使うのがよいでしょう。
- 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 を参照してください)。maxheaderlen が
Noneでなければ、maxheaderlen より長いヘッダー行を折り返し直します。0の場合は、どのヘッダーも折り返し直しません。 maxheaderlen がNone(デフォルト) の場合は、policy の設定に従ってヘッダーやその他のメッセージの行を折り返します。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 引数が追加されました。
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]"
オプション引数 mangle_from_ と maxheaderlen は、基底クラス
Generatorのものと同じです。
脚注