19.1.3. email.generator: MIME 文書の生成

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


よくある作業のひとつは、メッセージオブジェクト構造からフラットな電子メールテキストを生成することです。この作業は smtplibnntplib モジュールを使ってメッセージを送信したり、メッセージをコンソールに出力したりするときに必要になります。あるメッセージオブジェクト構造をとってきて、そこからフラットなテキスト文書を生成するのは Generator クラスの仕事です。

繰り返しになりますが、 email.parser モジュールと同じく、この機能はここでの定義済みジェネレータに制限されるわけではありません。これらはご自身でゼロから作りあげることもできます。しかしながら、定義済みのジェネレータはほとんどの電子メールを標準に沿ったやり方で生成する方法を知っていますし、MIME メッセージも非 MIME メッセージもとても上手く扱えます。さらにこれはフラットなテキストから Parser クラスを使ってメッセージ構造に変換し、それをまたフラットなテキストに戻しても、結果が冪等 (入力が出力と同じになる) [1] になるよう設計されています。一方で、プログラムによって構成された Message のジェネレータを使う場合、デフォルトの挿入によって Message オブジェクトを変えてしまうかもしれません。

bytes output can be generated using the BytesGenerator class. If the message object structure contains non-ASCII bytes, this generator’s flatten() method will emit the original bytes. Parsing a binary message and then flattening it with BytesGenerator should be idempotent for standards compliant messages.

email.generator モジュールからインポートされる Generator クラスで公開されているメソッドには、以下のようなものがあります:

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

Generator クラスのコンストラクタは outfp と呼ばれる file-like object を引数にとります。 outfpwrite() メソッドをサポートし、 print() 関数の出力ファイルとして使えるようになっている必要があります。

Optional mangle_from_ is a flag that, when True, puts a > character in front of any line in the body that starts exactly as From, i.e. From followed by a space at the beginning of the line. This is the only guaranteed portable way to avoid having such lines be mistaken for a Unix mailbox format envelope header separator (see WHY THE CONTENT-LENGTH FORMAT IS BAD for details). mangle_from_ defaults to True, but you might want to set this to False if you are not writing Unix mailbox format files.

オプション引数 maxheaderlen は連続していないヘッダの最大長を指定します。ひとつのヘッダ行が maxheaderlen (これは文字数です、tab は空白 8文字に展開されます) よりも長い場合、ヘッダは Header クラスで定義されているように途中で折り返され、間にはセミコロンが挿入されます。もしセミコロンが見つからない場合、そのヘッダは放置されます。ヘッダの折り返しを禁止するにはこの値にゼロを指定してください。デフォルトは 78 文字で、 RFC 2822 で推奨されている (ですが強制ではありません) 値です。

The policy keyword specifies a policy object that controls a number of aspects of the generator’s operation. If no policy is specified, then the policy attached to the message object passed to flatten is used.

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

これ以外のパブリックな Generator メソッドは以下のとおりです:

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

msg を基点とするメッセージオブジェクト構造体の文字表現を出力します。出力先のファイルにはこの Generator インスタンスが作成されたときに指定されたものが使われます。各 subpart は深さ優先順序 (depth-first) で出力され、得られるテキストは適切に MIME エンコードされたものになっています。

オプション引数 unixfrom は、基点となるメッセージオブジェクトの最初の RFC 2822 ヘッダが現れる前に、エンペローブヘッダ区切り文字列を出力することを強制するフラグです。そのメッセージオブジェクトがエンペローブヘッダをもたない場合、標準的なエンペローブヘッダが自動的に作成されます。デフォルトではこの値は False に設定されており、エンペローブヘッダ区切り文字列は出力されません。

注意: 各 subpart に関しては、エンペローブヘッダは出力されません。

Optional linesep specifies the line separator character used to terminate lines in the output. If specified it overrides the value specified by the msg‘s or Generator‘s policy.

Because strings cannot represent non-ASCII bytes, if the policy that applies when flatten is run has cte_type set to 8bit, Generator will operate as if it were set to 7bit. This means that messages parsed with a Bytes parser that have a Content-Transfer-Encoding of 8bit will be converted to a use a 7bit Content-Transfer-Encoding. Non-ASCII bytes in the headers will be RFC 2047 encoded with a charset of unknown-8bit.

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

clone(fp)

この Generator インスタンスの独立したクローンを生成し返します。オプションはすべて同一になっています。

write(s)

文字列 s を既定のファイルに出力します。ここでいう出力先は Generator コンストラクタに渡した outfp のことをさします。この関数はただ単に print() 関数で使われる Generator インスタンスに対してファイル操作風の API を提供するためだけのものです。

As a convenience, see the Message methods as_string() and str(aMessage), a.k.a. __str__(), which simplify the generation of a formatted string representation of a message object. For more detail, see email.message.

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

The constructor for the BytesGenerator class takes a binary file-like object called outfp for an argument. outfp must support a write() method that accepts binary data.

Optional mangle_from_ is a flag that, when True, puts a > character in front of any line in the body that starts exactly as From, i.e. From followed by a space at the beginning of the line. This is the only guaranteed portable way to avoid having such lines be mistaken for a Unix mailbox format envelope header separator (see WHY THE CONTENT-LENGTH FORMAT IS BAD for details). mangle_from_ defaults to True, but you might want to set this to False if you are not writing Unix mailbox format files.

オプション引数 maxheaderlen は連続していないヘッダの最大長を指定します。ひとつのヘッダ行が maxheaderlen (これは文字数です、tab は空白 8文字に展開されます) よりも長い場合、ヘッダは Header クラスで定義されているように途中で折り返され、間にはセミコロンが挿入されます。もしセミコロンが見つからない場合、そのヘッダは放置されます。ヘッダの折り返しを禁止するにはこの値にゼロを指定してください。デフォルトは 78 文字で、 RFC 2822 で推奨されている (ですが強制ではありません) 値です。

The policy keyword specifies a policy object that controls a number of aspects of the generator’s operation. If no policy is specified, then the policy attached to the message object passed to flatten is used.

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

これ以外のパブリックな BytesGenerator メソッドは以下のとおりです:

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

Print the textual representation of the message object structure rooted at msg to the output file specified when the BytesGenerator instance was created. Subparts are visited depth-first and the resulting text will be properly MIME encoded. If the policy option cte_type is 8bit (the default), then any bytes with the high bit set in the original parsed message that have not been modified will be copied faithfully to the output. If cte_type is 7bit, the bytes will be converted as needed using an ASCII-compatible Content-Transfer-Encoding. In particular, RFC-invalid non-ASCII bytes in headers will be encoded using the MIME unknown-8bit character set, thus rendering them RFC-compliant.

Messages parsed with a Bytes parser that have a Content-Transfer-Encoding of 8bit will be reconstructed as 8bit if they have not been modified.

オプション引数 unixfrom は、基点となるメッセージオブジェクトの最初の RFC 2822 ヘッダが現れる前に、エンペローブヘッダ区切り文字列を出力することを強制するフラグです。そのメッセージオブジェクトがエンペローブヘッダをもたない場合、標準的なエンペローブヘッダが自動的に作成されます。デフォルトではこの値は False に設定されており、エンペローブヘッダ区切り文字列は出力されません。

注意: 各 subpart に関しては、エンペローブヘッダは出力されません。

Optional linesep specifies the line separator character used to terminate lines in the output. If specified it overrides the value specified by the Generatoror msg‘s policy.

clone(fp)

この BytesGenerator インスタンスの独立したクローンを生成し返します。オプションはすべて同一になっています。

write(s)

Write the string s to the underlying file object. s is encoded using the ASCII codec and written to the write method of the outfp outfp passed to the BytesGenerator‘s constructor. This provides just enough file-like API for BytesGenerator instances to be used in the print() function.

バージョン 3.2 で追加.

email.generator モジュールはひとつの派生クラスも提供しています。これは DecodedGenerator と呼ばれるもので、 Generator 基底クラスと似ていますが、非 text 型の subpart を特定の書式でフォーマットされた表現形式で置きかえるところが違っています。

class email.generator.DecodedGenerator(outfp, mangle_from_=True, maxheaderlen=78, fmt=None)

このクラスは Generator から派生したもので、メッセージの subpart をすべて渡り歩きます。subpart の主形式が text だった場合、これはその subpart のペイロードをデコードして出力します。オプション引数 _mangle_from_ および maxheaderlen の意味は基底クラス Generator のそれと同じです。

Subpart の主形式が text ではない場合、オプション引数 fmt がそのメッセージペイロードのかわりのフォーマット文字列として使われます。 fmt%(keyword)s のような形式を展開し、以下のキーワードを認識します:

  • 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 です。こうすると以下の形式で出力します

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

脚注

[1]

ここではあなたが unixfrom 引数に適切な設定を使い、 maxheaderlen=0 (入力行がどんな長さでも元のものを維持します) をセットしていることを前提にしています。これでもなお厳密には正しくありません。多くの場合ヘッダの連続する空白が単一の空白に置き換えられるからです。これはいずれは修正されるべきバグです。