18.1.1. "email.message": 電子メールメッセージの表現
***************************************************

"Message" クラスは、 "email" パッケージの中心となるクラスです。これは
"email" オブジェクトモデルの基底クラスになっています。 "Message" はヘ
ッダフィールドを検索したりメッセージ本体にアクセスするための核となる機
能を提供します。

概念的には、("email.message" モジュールからインポートされる) "Message"
オブジェクトには *ヘッダ* と *ペイロード* が格納されています。ヘッダは
、 **RFC 2822** 形式のフィールド名およびフィールド値がコロンで区切られ
たものです。コロンはフィールド名またはフィールド値のどちらにも含まれま
せん。

ヘッダは大文字小文字を区別した形式で保存されますが、ヘッダ名が一致する
かどうかの検査は大文字小文字を区別せずにおこなうことができます。
*Unix-From* ヘッダまたは "From_" ヘッダとして知られるエンベロープヘッ
ダがひとつ存在することもあります。ペイロードは、単純なメッセージオブジ
ェクトの場合は単なる文字列ですが、 MIME コンテナ文書 (*multipart/** ま
たは *message/rfc822* など) の場合は "Message" オブジェクトのリストに
なっています。

"Message" オブジェクトは、メッセージヘッダにアクセスするためのマップ (
辞書) 形式のインタフェイスと、ヘッダおよびペイロードの両方にアクセスす
るための明示的なインタフェイスを提供します。これにはメッセージオブジェ
クトツリーからフラットなテキスト文書を生成したり、一般的に使われるヘッ
ダのパラメータにアクセスしたり、またオブジェクトツリーを再帰的にたどっ
たりするための便利なメソッドを含みます。

"Message" クラスのメソッドは以下のとおりです:

class email.message.Message

   コンストラクタは引数をとりません。

   as_string([unixfrom])

      メッセージ全体をフラットな文字列として返します。オプション
      *unixfrom* が "True" の場合、返される文字列にはエンベロープヘッ
      ダも含まれます。 *unixfrom* のデフォルトは "False" です。もし、
      文字列への変換を完全に行うためにデフォルト値を埋める必要がある場
      合、メッセージのフラット化は "Message" の変更を引き起こす可能性
      があります (例えば、MIME の境界が生成される、変更される等)。

      このメソッドは手軽に利用する事ができますが、必ずしも期待通りにメ
      ッセージをフォーマットするとは限りません。たとえば、これはデフォ
      ルトでは "From" で始まる行を変更してしまいます。以下の例のように
      "Generator" のインスタンスを生成して "flatten()" メソッドを直接
      呼び出せばより柔軟な処理を行う事ができます。

         from cStringIO import StringIO
         from email.generator import Generator
         fp = StringIO()
         g = Generator(fp, mangle_from_=False, maxheaderlen=60)
         g.flatten(msg)
         text = fp.getvalue()

   __str__()

      "as_string(unixfrom=True)()" と同じです。

   is_multipart()

      メッセージのペイロードが子 "Message" オブジェクトからなるリスト
      であれば "True" を返し、そうでなければ "False" を返します。
      "is_multipart()" が "False" を返した場合は、ペイロードは文字列オ
      ブジェクトである必要があります。

   set_unixfrom(unixfrom)

      メッセージのエンベロープヘッダを *unixfrom* に設定します。これは
      文字列である必要があります。

   get_unixfrom()

      メッセージのエンベロープヘッダを返します。エンベロープヘッダが設
      定されていない場合は "None" が返されます。

   attach(payload)

      与えられた *payload* を現在のペイロードに追加します。この時点で
      のペイロードは "None" か、あるいは "Message" オブジェクトのリス
      トである必要があります。このメソッドの実行後、ペイロードは必ず
      "Message" オブジェクトのリストになります。ペイロードにスカラーオ
      ブジェクト (文字列など) を格納したい場合は、かわりに
      "set_payload()" を使ってください。

   get_payload([i[, decode]])

      現在のペイロードへの参照を返します。これは "is_multipart()" が
      "True" の場合 "Message" オブジェクトのリストになり、
      "is_multipart()" が "False" の場合は文字列になります。ペイロード
      がリストの場合、リストを変更することはそのメッセージのペイロード
      を変更することになります。

      オプション引数の *i* がある場合、 "is_multipart()" が "True" な
      らば "get_payload()" はペイロード中で 0 から数えて *i* 番目の要
      素を返します。 *i* が 0 より小さい場合、あるいはペイロードの個数
      以上の場合は "IndexError" が発生します。ペイロードが文字列 (つま
      り "is_multipart()" が "False") にもかかわらず *i* が与えられた
      ときは "TypeError" が発生します。

      オプションの *decode* はそのペイロードが *Content-Transfer-
      Encoding* ヘッダに従ってデコードされるべきかどうかを指示するフラ
      グです。この値が "True" でメッセージが multipart ではない場合、
      ペイロードはこのヘッダの値が "quoted-printable" または "base64"
      のときにかぎりデコードされます。これ以外のエンコーディングが使わ
      れている場合、 *Content-Transfer-Encoding* ヘッダがない場合、あ
      るいは曖昧な base64 データが含まれる場合は、ペイロードはそのまま
      (デコードされずに) 返されます。もしメッセージが multipart で
      *decode* フラグが "True" の場合は "None" が返されます。 *decode*
      のデフォルト値は "False" です。

   set_payload(payload[, charset])

      メッセージ全体のオブジェクトのペイロードを *payload* に設定しま
      す。ペイロードの形式をととのえるのは呼び出し側の責任です。オプシ
      ョンの *charset* はメッセージのデフォルト文字セットを設定します
      。詳しくは "set_charset()" を参照してください。

      バージョン 2.2.2 で変更: *charset* 引数を追加。

   set_charset(charset)

      ペイロードの文字セットを *charset* に変更します。ここには
      "Charset" インスタンス ("email.charset" 参照)、文字セット名をあ
      らわす文字列、あるいは "None" のいずれかが指定できます。文字列を
      指定した場合、これは "Charset" インスタンスに変換されます。
      *charset* が "None" の場合、 "charset" パラメータは *Content-
      Type* ヘッダから除去されます (それ以外にメッセージの変形は行われ
      ません)。これ以外のものを文字セットとして指定した場合、
      "TypeError" が発生します。

      *MIME-Version* ヘッダが存在しなければ、追加されます。 *Content-
      Type* ヘッダが存在しなければ、 *text/plain* を値として追加されま
      す。 *Content-Type* が存在していてもいなくても、 "charset" パラ
      メタは *charset.output_charset* に設定されます。
      *charset.input_charset* と *charset.output_charset* が異なるなら
      、ペイロードは *output_charset* に再エンコードされます。
      *Content-Transfer-Encoding* ヘッダが存在しなければ、ペイロードは
      、必要なら指定された "Charset" を使って transfer エンコードされ
      、適切な値のヘッダが追加されます。 *Content-Transfer-Encoding*
      ヘッダがすでに存在すれば、ペイロードはすでにその *Content-
      Transfer-Encoding* によって正しくエンコードされたものと見なされ
      、変形されません。

      ここでいうメッセージとは、unicode 文字列か
      *charset.input_charset* でエンコードされたペイロードを持つ
      *text/** 形式のものを仮定しています。これは、プレーンテキスト形
      式を生成する際に *charset.output_charset* と転送 (transfer) エン
      コードに、エンコードまたは変換されます。MIME ヘッダ (*MIME-
      Version*, *Content-Type*, *Content-Transfer-Encoding*) は必要に
      応じて追加されます。

      バージョン 2.2.2 で追加.

   get_charset()

      そのメッセージ中のペイロードの "Charset" インスタンスを返します
      。

      バージョン 2.2.2 で追加.

   以下のメソッドは、メッセージの **RFC 2822** ヘッダにアクセスするた
   めのマップ (辞書) 形式のインタフェイスを実装したものです。これらの
   メソッドと、通常のマップ (辞書) 型はまったく同じ意味をもつわけでは
   ないことに注意してください。たとえば辞書型では、同じキーが複数ある
   ことは許されていませんが、ここでは同じメッセージヘッダが複数ある場
   合があります。また、辞書型では "keys()" で返されるキーの順序は保証
   されていませんが、 "Message" オブジェクト内のヘッダはつねに元のメッ
   セージ中に現れた順序、あるいはそのあとに追加された順序で返されます
   。削除され、その後ふたたび追加されたヘッダはリストの一番最後に現れ
   ます。

   こういった意味のちがいは意図的なもので、最大の利便性をもつようにつ
   くられています。

   注意: どんな場合も、メッセージ中のエンベロープヘッダはこのマップ形
   式のインタフェイスには含まれません。

   __len__()

      複製されたものもふくめてヘッダ数の合計を返します。

   __contains__(name)

      メッセージオブジェクトが *name* という名前のフィールドを持ってい
      れば true を返します。この検査では名前の大文字小文字は区別されま
      せん。*name* は最後にコロンをふくんでいてはいけません。このメソ
      ッドは以下のように "in" 演算子で使われます:

         if 'message-id' in myMessage:
             print 'Message-ID:', myMessage['message-id']

   __getitem__(name)

      指定された名前のヘッダフィールドの値を返します。 *name* は最後に
      コロンをふくんでいてはいけません。そのヘッダがない場合は "None"
      が返され、 "KeyError" 例外は発生しません。

      注意: 指定された名前のフィールドがメッセージのヘッダに2回以上現
      れている場合、どちらの値が返されるかは未定義です。ヘッダに存在す
      るフィールドの値をすべて取り出したい場合は "get_all()" メソッド
      を使ってください。

   __setitem__(name, val)

      メッセージヘッダに *name* という名前の *val* という値をもつフィ
      ールドをあらたに追加します。このフィールドは現在メッセージに存在
      するフィールドのいちばん後に追加されます。

      注意: このメソッドでは、すでに同一の名前で存在するフィールドは上
      書き *されません*。もしメッセージが名前 *name* をもつフィールド
      をひとつしか持たないようにしたければ、最初にそれを除去してくださ
      い。たとえば:

         del msg['subject']
         msg['subject'] = 'Python roolz!'

   __delitem__(name)

      メッセージのヘッダから、*name* という名前をもつフィールドをすべ
      て除去します。たとえこの名前をもつヘッダが存在していなくても例外
      は発生しません。

   has_key(name)

      メッセージが *name* という名前をもつヘッダフィールドを持っていれ
      ば真を、そうでなければ偽を返します。

   keys()

      メッセージ中にあるすべてのヘッダのフィールド名のリストを返します
      。

   values()

      メッセージ中にあるすべてのフィールドの値のリストを返します。

   items()

      メッセージ中にあるすべてのヘッダのフィールド名とその値を 2-タプ
      ルのリストとして返します。

   get(name[, failobj])

      指定された名前をもつフィールドの値を返します。これは指定された名
      前がないときにオプション引数の *failobj* (デフォルトでは "None")
      を返すことをのぞけば、 "__getitem__()" と同じです。

   さらに、役に立つメソッドをいくつか紹介します:

   get_all(name[, failobj])

      *name* の名前をもつフィールドのすべての値からなるリストを返しま
      す。該当する名前のヘッダがメッセージ中に含まれていない場合は
      *failobj* (デフォルトでは "None") が返されます。

   add_header(_name, _value, **_params)

      拡張ヘッダ設定。このメソッドは "__setitem__()" と似ていますが、
      追加のヘッダ・パラメータをキーワード引数で指定できるところが違っ
      ています。 *_name* に追加するヘッダフィールドを、 *_value* にそ
      のヘッダの *最初の* 値を渡します。

      キーワード引数辞書 *_params* の各項目ごとに、そのキーがパラメー
      タ名として扱われ、キー名にふくまれるアンダースコアはハイフンに置
      換されます (アンダースコアは、Python 識別子としてハイフンを使え
      ないための代替です)。ふつう、パラメータの値が "None" 以外のとき
      は、 "key="value"" の形で追加されます。パラメータの値が "None"
      のときはキーのみが追加されます。値が非 ASCII 文字を含むなら、そ
      れは "(CHARSET, LANGUAGE, VALUE)" の形式の 3 タプルでなくてはな
      りません。ここで "CHARSET" はその値をエンコードするのに使われる
      文字セットを指示する文字列で、 "LANGUAGE" は通常 "None" か空文字
      列にでき (これら以外で指定出来るものについては **RFC 2231** を参
      照してください)、 "VALUE" は非 ASCII コードポイントを含む文字列
      値です。

      以下はこの使用例です:

         msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

      こうするとヘッダには以下のように追加されます

         Content-Disposition: attachment; filename="bud.gif"

      非 ASCII 文字を使った例:

         msg.add_header('Content-Disposition', 'attachment',
                        filename=('iso-8859-1', '', 'Fußballer.ppt'))

      は、以下のようになります

         Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"

   replace_header(_name, _value)

      ヘッダの置換。 *_name* と一致するヘッダで最初に見つかったものを
      置き換えます。このときヘッダの順序とフィールド名の大文字小文字は
      保存されます。一致するヘッダがない場合、 "KeyError" が発生します
      。

      バージョン 2.2.2 で追加.

   get_content_type()

      そのメッセージの content-type を返します。返された文字列は強制的
      に小文字で *maintype/subtype* の形式に変換されます。メッセージ中
      に *Content-Type* ヘッダがない場合、デフォルトの content-type は
      "get_default_type()" が返す値によって与えられます。 **RFC 2045**
      によればメッセージはつねにデフォルトの content-type をもっている
      ので、 "get_content_type()" はつねになんらかの値を返すはずです。

      **RFC 2045** はメッセージのデフォルト content-type を、それが
      *multipart/digest* コンテナに現れているとき以外は *text/plain*
      に規定しています。あるメッセージが *multipart/digest* コンテナ中
      にある場合、その content-type は *message/rfc822* になります。も
      し *Content-Type* ヘッダが適切でない content-type 書式だった場合
      、 **RFC 2045** はそれのデフォルトを *text/plain* として扱うよう
      定めています。

      バージョン 2.2.2 で追加.

   get_content_maintype()

      そのメッセージの主 content-type を返します。これは
      "get_content_type()" によって返される文字列の *maintype* 部分で
      す。

      バージョン 2.2.2 で追加.

   get_content_subtype()

      そのメッセージの副 content-type (sub content-type、subtype) を返
      します。これは "get_content_type()" によって返される文字列の
      *subtype* 部分です。

      バージョン 2.2.2 で追加.

   get_default_type()

      デフォルトの content-type を返します。ほどんどのメッセージではデ
      フォルトの content-type は *text/plain* ですが、メッセージが
      *multipart/digest* コンテナに含まれているときだけ例外的に
      *message/rfc822* になります。

      バージョン 2.2.2 で追加.

   set_default_type(ctype)

      デフォルトの content-type を設定します。 *ctype* は *text/plain*
      あるいは *message/rfc822* である必要がありますが、強制ではありま
      せん。デフォルトの content-type はヘッダの *Content-Type* には格
      納されません。

      バージョン 2.2.2 で追加.

   get_params([failobj[, header[, unquote]]])

      メッセージの *Content-Type* パラメータをリストとして返します。返
      されるリストはキー/値の組からなる2要素タプルが連なったものであり
      、これらは "'='" 記号で分離されています。 "'='" の左側はキーにな
      り、右側は値になります。パラメータ中に "'='" がなかった場合、値
      の部分は空文字列になり、そうでなければその値は "get_param()" で
      説明されている形式になります。また、オプション引数 *unquote* が
      "True" (デフォルト) である場合、この値は unquote されます。

      オプション引数 *failobj* は、 *Content-Type* ヘッダが存在しなか
      った場合に返すオブジェクトです。オプション引数 *header* には
      *Content-Type* のかわりに検索すべきヘッダを指定します。

      バージョン 2.2.2 で変更: *unquote* 引数の追加。

   get_param(param[, failobj[, header[, unquote]]])

      メッセージの *Content-Type* ヘッダ中のパラメータ *param* を文字
      列として返します。そのメッセージ中に *Content-Type* ヘッダが存在
      しなかった場合、 *failobj*  (デフォルトは "None") が返されます。

      オプション引数 *header* が与えられた場合、 *Content-Type* のかわ
      りにそのヘッダが使用されます。

      パラメータのキー比較は常に大文字小文字を区別しません。返り値は文
      字列か 3 要素のタプルで、タプルになるのはパラメータが **RFC
      2231** エンコードされている場合です。3 要素タプルの場合、各要素
      の値は "(CHARSET, LANGUAGE, VALUE)" の形式になっています。
      "CHARSET" と "LAGUAGE" は "None" になることがあり、その場合
      "VALUE" は "us-ascii" 文字セットでエンコードされているとみなさな
      ければならないので注意してください。普段は "LANGUAGE" を無視でき
      ます。

      この関数を使うアプリケーションが、パラメータが **RFC 2231** 形式
      でエンコードされているかどうかを気にしないのであれば、
      "email.utils.collapse_rfc2231_value()" に "get_param()" の返り値
      を渡して呼び出すことで、このパラメータをひとつにまとめることがで
      きます。この値がタプルならばこの関数は適切にデコードされた
      Unicode 文字列を返し、そうでない場合は unquote された元の文字列
      を返します。たとえば:

         rawparam = msg.get_param('foo')
         param = email.utils.collapse_rfc2231_value(rawparam)

      いずれの場合もパラメータの値は (文字列であれ3要素タプルの
      "VALUE" 項目であれ) つねに unquote されます。ただし、*unquote*
      が "False" に指定されている場合は unquote されません。

      バージョン 2.2.2 で変更: *unquote* 引数の追加、3要素タプルが返り
      値になる可能性あり。

   set_param(param, value[, header[, requote[, charset[, language]]]])

      *Content-Type* ヘッダ中のパラメータを設定します。指定されたパラ
      メータがヘッダ中にすでに存在する場合、その値は *value* に置き換
      えられます。 *Content-Type* ヘッダがまだこのメッセージ中に存在し
      ていない場合、 **RFC 2045** にしたがいこの値には *text/plain* が
      設定され、新しいパラメータ値が末尾に追加されます。

      オプション引数 *header* が与えられた場合、 *Content-Type* のかわ
      りにそのヘッダが使用されます。オプション引数 *requote* が
      "False" でない限り、この値は quote されます (デフォルトは
      "True")。

      オプション引数 *charset* が与えられると、そのパラメータは **RFC
      2231** に従ってエンコードされます。オプション引数 *language* は
      RFC 2231 の言語を指定しますが、デフォルトではこれは空文字列とな
      ります。 *charset* と *language* はどちらも文字列である必要があ
      ります。

      バージョン 2.2.2 で追加.

   del_param(param[, header[, requote]])

      指定されたパラメータを *Content-Type* ヘッダ中から完全にとりのぞ
      きます。ヘッダはそのパラメータと値がない状態に書き換えられます。
      *requote* が "False" でない限り (デフォルトでは "True" です)、す
      べての値は必要に応じて quote されます。オプション変数 *header*
      が与えられた場合、 *Content-Type* のかわりにそのヘッダが使用され
      ます。

      バージョン 2.2.2 で追加.

   set_type(type[, header][, requote])

      *Content-Type* ヘッダの maintype と subtype を設定します。
      *type* は *maintype/subtype* という形の文字列でなければなりませ
      ん。それ以外の場合は "ValueError" が発生します。

      このメソッドは *Content-Type* ヘッダを置き換えますが、すべてのパ
      ラメータはそのままにします。 *requote* が "False" の場合、これは
      すでに存在するヘッダを quote せず放置しますが、そうでない場合は
      自動的に quote します (デフォルト動作)。

      オプション変数 *header* が与えられた場合、 *Content-Type* のかわ
      りにそのヘッダが使用されます。 *Content-Type* ヘッダが設定される
      場合には、 *MIME-Version* ヘッダも同時に付加されます。

      バージョン 2.2.2 で追加.

   get_filename([failobj])

      そのメッセージ中の *Content-Disposition* ヘッダにある、
      "filename" パラメータの値を返します。目的のヘッダに "filename"
      パラメータがない場合には *Content-Type* ヘッダにある "name" パラ
      メータを探します。それも無い場合またはヘッダが無い場合には
      *failobj* が返されます。返される文字列はつねに
      "email.utils.unquote()" によって unquote されます。

   get_boundary([failobj])

      そのメッセージ中の *Content-Type* ヘッダにある、 "boundary" パラ
      メータの値を返します。目的のヘッダが欠けていたり、 "boundary" パ
      ラメータがない場合には *failobj* が返されます。返される文字列は
      つねに "email.utils.unquote()" によって unquote されます。

   set_boundary(boundary)

      メッセージ中の *Content-Type* ヘッダにある、 "boundary" パラメー
      タに値を設定します。 "set_boundary()" は必要に応じて *boundary*
      を quote します。そのメッセージが *Content-Type* ヘッダを含んで
      いない場合、 "HeaderParseError" が発生します。

      注意: このメソッドを使うのは、古い *Content-Type* ヘッダを削除し
      て新しい boundary をもったヘッダを "add_header()" で足すのとは少
      し違います。 "set_boundary()" は一連のヘッダ中での *Content-
      Type* ヘッダの位置を保つからです。しかし、これは元の *Content-
      Type* ヘッダ中に存在していた連続する行の順番までは *保ちません*
      。

   get_content_charset([failobj])

      そのメッセージ中の *Content-Type* ヘッダにある、 "charset" パラ
      メータの値を返します。値はすべて小文字に変換されます。メッセージ
      中に *Content-Type* がなかったり、このヘッダ中に "charaset" パラ
      メータがない場合には *failobj* が返されます。

      注意: これは "get_charset()" メソッドとは異なります。こちらのほ
      うは文字列のかわりに、そのメッセージボディのデフォルトエンコーデ
      ィングの "Charset" インスタンスを返します。

      バージョン 2.2.2 で追加.

   get_charsets([failobj])

      メッセージ中に含まれる文字セットの名前をすべてリストにして返しま
      す。そのメッセージが *multipart* である場合、返されるリストの各
      要素がそれぞれの subpart のペイロードに対応します。それ以外の場
      合、これは長さ 1 のリストを返します。

      リスト中の各要素は文字列であり、これは対応する subpart 中のそれ
      ぞれの *Content-Type* ヘッダにある "charset" の値です。しかし、
      その subpart が *Content-Type* をもってないか、 "charset" がない
      か、あるいは MIME maintype が *text* でないいずれかの場合には、
      リストの要素として *failobj* が返されます。

   walk()

      "walk()" メソッドは多目的のジェネレータで、これはあるメッセージ
      オブジェクトツリー中のすべての part および subpart をわたり歩く
      のに使えます。順序は深さ優先です。おそらく典型的な用法は、
      "walk()" を "for" ループ中でのイテレータとして使うことでしょう。
      ループを一回まわるごとに、次の subpart が返されるのです。

      以下の例は、 multipart メッセージのすべての part において、その
      MIME タイプを表示していくものです。

         >>> for part in msg.walk():
         ...     print part.get_content_type()
         multipart/report
         text/plain
         message/delivery-status
         text/plain
         text/plain
         message/rfc822

   バージョン 2.5 で変更: 以前の非推奨メソッド "get_type()" 、
   "get_main_type()" 、 "get_subtype()" は削除されました。

   "Message" オブジェクトはオプションとして 2つのインスタンス属性をと
   ることができます。これはある MIME メッセージからプレーンテキストを
   生成するのに使うことができます。

   preamble

      MIME ドキュメントの形式では、ヘッダ直後にくる空行と最初の
      multipart 境界をあらわす文字列のあいだにいくらかのテキスト (訳注
      : preamble, 序文) を埋めこむことを許しています。このテキストは標
      準的な MIME の範疇からはみ出しているので、MIME 形式を認識するメ
      ールソフトからこれらは通常まったく見えません。しかしメッセージの
      テキストを生で見る場合、あるいはメッセージを MIME 対応していない
      メールソフトで見る場合、このテキストは目に見えることになります。

      *preamble* 属性は MIME ドキュメントに加えるこの最初の MIME 範囲
      外テキストを含んでいます。 "Parser" があるテキストをヘッダ以降に
      発見したが、それはまだ最初の MIME 境界文字列が現れる前だった場合
      、パーザはそのテキストをメッセージの *preamble* 属性に格納します
      。 "Generator" がある MIME メッセージからプレーンテキスト形式を
      生成するときメッセージが *preamble* 属性を持つことが発見されれば
      、これはそのテキストをヘッダと最初の MIME 境界の間に挿入します。
      詳細は "email.parser" および "email.generator" を参照してくださ
      い。

      注意: そのメッセージに preamble がない場合、*preamble* 属性には
      "None" が格納されます。

   epilogue

      *epilogue* 属性はメッセージの最後の MIME 境界文字列からメッセー
      ジ末尾までのテキストを含むもので、それ以外は *preamble* 属性と同
      じです。

      バージョン 2.5 で変更: "Generator" でファイル終端に改行を出力す
      るため、 epilogue に空文字列を設定する必要はなくなりました。

   defects

      *defects* 属性はメッセージを解析する途中で検出されたすべての問題
      点 (defect、障害) のリストを保持しています。解析中に発見されうる
      障害についてのより詳細な説明は "email.errors" を参照してください
      。

      バージョン 2.4 で追加.
