# 18.1. `email` --- 電子メールと MIME 処理のためのパッケージ

バージョン 2.2 で追加.

`email` パッケージは電子メールのメッセージを管理するライブラリです。これには MIME やそれ以外の RFC 2822 ベースのメッセージ文書もふくまれます。このパッケージはいくつかの古い標準パッケージ、 `rfc822`, `mimetools`, `multifile` などにふくまれていた機能のほとんどを持ち、加えて標準ではなかった `mimecntl` などの機能も含んでいます。このパッケージは、とくに電子メールのメッセージを SMTP (RFC 2821)、 NNTP、その他のサーバに送信するために作られているというわけでは ありません 。それは `smtplib`, `nntplib` モジュールなどの機能です。 `email` パッケージは RFC 2822 に加えて、 RFC 2045, RFC 2046, RFC 2047 および RFC 2231 など MIME 関連の RFC をサポートしており、できるかぎり RFC に準拠することをめざしています。

`email` パッケージの一番の特徴は、電子メールの内部表現である オブジェクトモデル と、電子メールメッセージの解析および生成とを分離していることです。 `email` パッケージを使うアプリケーションは基本的にはオブジェクトを処理することができます。メッセージに子オブジェクトを追加したり、メッセージから子オブジェクトを削除したり、内容を完全に並べかえたり、といったことができます。フラットなテキスト文書からオブジェクトモデルへの変換、またそこからフラットな文書へと戻す変換はそれぞれ別々の解析器 (パーサ) と生成器 (ジェネレータ) が担当しています。また、一般的な MIME オブジェクトタイプのいくつかについては手軽なサブクラスが存在しており、メッセージフィールド値を抽出したり解析したり、 RFC 準拠の日付を生成したりなどのよくおこわれるタスクについてはいくつかの雑用ユーティリティもついています。

以下の節では `email` パッケージの機能を説明します。説明の順序は多くのアプリケーションで一般的な使用順序にもとづいています。まず、電子メールメッセージをファイルあるいはその他のソースからフラットなテキスト文書として読み込み、つぎにそのテキストを解析して電子メールのオブジェクト構造を作成し、その構造を操作して、最後にオブジェクトツリーをフラットなテキストに戻す、という順序になっています。

このオブジェクト構造は、まったくのゼロから作りだしたものであってもいっこうにかまいません。この場合も上と似たような作業順序になるでしょう。

またここには `email` パッケージが提供するすべてのクラスおよびモジュールに関する説明と、 `email` パッケージを使っていくうえで遭遇するかもしれない例外クラス、いくつかの補助ユーティリティ、そして少々のサンプルも含まれています。古い `mimelib` や前バージョンの `email` パッケージのユーザのために、現行バージョンとの違いと移植についての節も設けてあります。

`email` パッケージ文書の内容

- 18.1.1. `email.message`: 電子メールメッセージの表現
- 18.1.2. `email.parser`: 電子メールメッセージを解析(パース)する
  - 18.1.2.1. FeedParser API
  - 18.1.2.2. Parser クラス API
  - 18.1.2.3. 追記事項
- 18.1.3. `email.generator`: MIME 文書を生成する
- 18.1.4. `email.mime`: ゼロからのメールと MIME オブジェクトの作成
- 18.1.5. `email.header`: 国際化されたヘッダ
- 18.1.6. `email.charset`: 文字集合の表現
- 18.1.7. `email.encoders`: エンコーダ
- 18.1.8. `email.errors`: 例外及び欠陥クラス
- 18.1.9. `email.utils`: 多方面のユーティリティ
- 18.1.10. `email.iterators`: イテレータ
- 18.1.11. `email`: 使用例

参考

`smtplib` モジュール
  SMTP プロトコルクライアント
`nntplib` モジュール
  NNTP プロトコルクライアント

## 18.1.12. パッケージの履歴

このテーブルは email パッケージのリリース履歴を表しています。それぞれのバージョンと、それが同梱された Python のバージョンとの関連が示されています。このドキュメントでの、追加/変更されたバージョンの表記は email パッケージのバージョン ではなく、Pythonのバージョンです。このテーブルは Python の各バージョン間の email パッケージの互換性も示しています。

email バージョン | 配布 | 互換
--- | --- | ---
`1.x` | Python 2.2.0 から Python 2.2.1 まで | もうサポートされません
`2.5` | Python 2.2.2+ と Python 2.3 | Python 2.1 から 2.5 まで
`3.0` | Python 2.4 | Python 2.3 から 2.5 まで
`4.0` | Python 2.5 | Python 2.3 から 2.5 まで

以下は `email` バージョン4と3の間のおもな差分です:

- 全モジュールが PEP 8 標準にあわせてリネームされました。たとえば、version 3 でのモジュール `email.Message` は version 4 では `email.message` になりました。

- 新しいサブパッケージ `email.mime` が追加され、 version 3 の `email.MIME*` は、 `email.mime` のサブパッケージにまとめられました。たとえば、version 3 での `email.MIMEText` は、 `email.mime.text` になりました。

  Python 2.6までは version 3 の名前も有効です。

- `email.mime.application` モジュールが追加されました。これは `MIMEApplication` クラスを含んでいます。

- version 3 で推奨されないとされた機能は削除されました。これらは `Generator.__call__()`, `Message.get_type()`, `Message.get_main_type()`, `Message.get_subtype()` を含みます。

- RFC 2331 サポートの修正が追加されました。これは `Message.get_param` などの関数の返り値を変更します。いくつかの環境では、3 つ組のタプルで返されていた値が 1 つの文字列で返されます (とくに、全ての拡張パラメータセグメントがエンコードされていなかった場合、予測されていた language や charset の指定がないと、返り値は単純な文字列になります)。過去の版では % デコードがエンコードされているセグメントおよびエンコードされていないセグメントに対して行われましたが、エンコードされたセグメントのみで行われるようになりました。

`email` バージョン 3 とバージョン 2 との違いは以下のようなものです:

- `FeedParser` クラスが新しく導入され、 `Parser` クラスは `FeedParser` を使って実装されるようになりました。このパーザは non-strict なものであり、解析はベストエフォート方式でおこなわれ解析中に例外を発生させることはありません。解析中に発見された問題はそのメッセージの defect (障害) 属性に保存されます。
- バージョン 2 で `DeprecationWarning` を発生していた API はすべて削除されました。以下のものが含まれています: `MIMEText` コンストラクタに渡す引数 _encoder 、 `Message.add_payload()` メソッド、 `Utils.dump_address_pair()` 関数、そして `Utils.decode()` と `Utils.encode()` です。
- 新しく以下の関数が `DeprecationWarning` を発生するようになりました: `Generator.__call__()`, `Message.get_type()`, `Message.get_main_type()`, `Message.get_subtype()`, そして `Parser` クラスに対する strict 引数です。これらは email の将来のバージョンで撤廃される予定です。
- Python 2.3 以前はサポートされなくなりました。

`email` バージョン 2 とバージョン 1 との違いは以下のようなものです:

- `email.Header` モジュールおよび `email.Charset` モジュールが追加されています。

- `Message` インスタンスの Pickle 形式が変わりました。が、これは正式に定義されたことは一度もないので (そしてこれからも)、この変更は互換性の欠如とはみなされていません。ですがもしお使いのアプリケーションが `Message` インスタンスを pickle あるいは unpickle しているなら、現在 `email` バージョン 2 では `Message` インスタンスがプライベート変数 _charset および _default_type を含むようになったということに注意してください。

- `Message` クラス中のいくつかのメソッドは推奨されなくなったか、あるいは呼び出し形式が変更になっています。また、多くの新しいメソッドが追加されています。詳しくは `Message` クラスの文書を参照してください。これらの変更は完全に下位互換になっているはずです。

- message/rfc822 形式のコンテナは、見た目上のオブジェクト構造が変わりました。 `email` バージョン 1 ではこの content type はスカラー形式のペイロードとして表現されていました。つまり、コンテナメッセージの `is_multipart()` は false を返し、 `get_payload()` はリストオブジェクトではなく単一の `Message` インスタンスを直接返すようになっていたのです。

  この構造はパッケージ中のほかの部分と整合がとれていなかったため、 message/rfc822 形式のオブジェクト表現形式が変更されました。 `email` バージョン 2 では、コンテナは `is_multipart()` で `True` を返し* ます。また `get_payload()` はひとつの `Message` インスタンスを要素とするリストを返すようになりました。

  注意: ここは下位互換が完全には成りたたなくなっている部分のひとつです。けれどもあらかじめ `get_payload()` が返すタイプをチェックするようになっていれば問題にはなりません。ただ message/rfc822 形式のコンテナを `Message` インスタンスにじかに `set_payload()` しないようにさえすればよいのです。

- `Parser` コンストラクタに strict 引数が追加され、 `parse()` および `parsestr()` メソッドには headersonly 引数がつきました。 strict フラグはまた `email.message_from_file()` と `email.message_from_string()` にも追加されています。

- `Generator.__call__()` はもはや推奨されなくなりました。かわりに `Generator.flatten` を使ってください。また、 `Generator` クラスには `clone()` メソッドが追加されています。

- `email.generator` モジュールに `DecodedGenerator` クラスが加わりました。

- 中間的な基底クラスである `MIMENonMultipart` および `MIMEMultipart` がクラス階層の中に追加され、ほとんどの MIME 関係の派生クラスがこれを介するようになっています。

- `MIMEText` コンストラクタの _encoder 引数は推奨されなくなりました。いまやエンコーダは _charset 引数にもとづいて暗黙のうちに決定されます。

- `email.utils` モジュールにおける以下の関数は推奨されなくなりました: `dump_address_pairs()`, `decode()`, および `encode()` 。また、このモジュールには以下の関数が追加されています: `make_msgid()`, `decode_rfc2231()`, `encode_rfc2231()` そして `decode_params()` 。

- Public ではない関数 `email.iterators._structure()` が追加されました。

## 18.1.13. `mimelib` との違い

`email` パッケージはもともと mimelib と呼ばれる個別のライブラリからつくられたものです。その後変更が加えられ、メソッド名がより一貫したものになり、いくつかのメソッドやモジュールが加えられたりはずされたりしました。いくつかのメソッドでは、その意味も変更されています。しかしほとんどの部分において、 `mimelib` パッケージで使うことのできた機能は、ときどきその方法が変わってはいるものの `email` パッケージでも使用可能です。 `mimelib` パッケージと `email` パッケージの間の下位互換性はあまり優先はされませんでした。

以下では `mimelib` パッケージと `email` パッケージにおける違いを簡単に説明し、それに沿ってアプリケーションを移植するさいの指針を述べています。

おそらく 2つのパッケージのもっとも明らかな違いは、パッケージ名が `email` に変更されたことでしょう。さらにトップレベルのパッケージが以下のように変更されました:

- `messageFromString()` は `message_from_string()` に名前が変更されました。
- `messageFromFile()` は `message_from_file()` に名前が変更されました。

`Message` クラスでは、以下のような違いがあります:

- `asString()` メソッドは `as_string()` に名前が変更されました。
- `ismultipart()` メソッドは `is_multipart()` に名前が変更されました。
- `get_payload()` メソッドはオプション引数として decode をとるようになりました。
- `getall()` メソッドは `get_all()` に名前が変更されました。
- `addheader()` メソッドは `add_header()` に名前が変更されました。
- `gettype()` メソッドは `get_type()` に名前が変更されました。
- `getmaintype()` メソッドは `get_main_type()` に名前が変更されました。
- `getsubtype()` メソッドは `get_subtype()` に名前が変更されました。
- `getparams()` メソッドは `get_params()` に名前が変更されました。また、従来の `getparams()` は文字列のリストを返していましたが、 `get_params()` は 2-タプルのリストを返すようになっています。これはそのパラメータのキーと値の組が、 `'='` 記号によって分離されたものです。
- `getparam()` メソッドは `get_param()` に名前が変更されました。
- `getcharsets()` メソッドは `get_charsets()` に名前が変更されました。
- `getfilename()` メソッドは `get_filename()` に名前が変更されました。
- `getboundary()` は `get_boundary()` に名前が変更されました。
- `setboundary()` メソッドは `set_boundary()` に名前が変更されました。
- `getdecodedpayload()` メソッドは廃止されました。これと同様の機能は `get_payload()` メソッドの decode フラグに 1 を渡すことで実現できます。
- `getpayloadastext()` メソッドは廃止されました。これと同様の機能は `email.generator` モジュールの `DecodedGenerator` クラスによって提供されます。
- `getbodyastext()` メソッドは廃止されました。これと同様の機能は `email.iterators` モジュールにある `typed_subpart_iterator()` を使ってイテレータを作ることにより実現できます。

`Parser` クラスは、その public なインターフェイスは変わっていませんが、これはより一層かしこくなって message/delivery-status 形式のメッセージを認識するようになりました。これは配送状態通知 [1] において、各ヘッダブロックを表す独立した `Message` サブパートを含むひとつの `Message` インスタンスとして表現されます。

`Generator` クラスは、その public なインターフェイスは変わっていませんが、 `email.generator` モジュールに新しいクラスが加わりました。 `DecodedGenerator` と呼ばれるこのクラスは以前 `Message.getpayloadastext()` メソッドで使われていた機能のほとんどを提供します。

また、以下のモジュールおよびクラスが変更されています:

- `MIMEBase` クラスのコンストラクタ引数 _major と _minor は、それぞれ _maintype と _subtype に変更されています。

- `Image` クラスおよびモジュールは `MIMEImage` に名前が変更されました。_minor 引数も _subtype に名前が変更されています。

- `Text` クラスおよびモジュールは `MIMEText` に名前が変更されました。_minor 引数も _subtype に名前が変更されています。

- `MessageRFC822` クラスおよびモジュールは `MIMEMessage` に名前が変更されました。注意: 従来バージョンの `mimelib` では、このクラスおよびモジュールは `RFC822` という名前でしたが、これは大文字小文字を区別しないファイルシステムでは Python の標準ライブラリモジュール `rfc822` と名前がかち合ってしまっていました。

  また、 `MIMEMessage` クラスはいまや message main type をもつあらゆる種類の MIME メッセージを表現できるようになりました。これはオプション引数として、MIME subtype を指定する _subtype 引数をとることができるようになっています。デフォルトでは、 _subtype は rfc822 になります。

`mimelib` では、 `address` および `date` モジュールでいくつかのユーティリティ関数が提供されていました。これらの関数はすべて `email.utils` モジュールの中に移されています。

`MsgReader` クラスおよびモジュールは廃止されました。これにもっとも近い機能は `email.iterators` モジュール中の `body_line_iterator()` 関数によって提供されています。

脚注

[1] | 配送状態通知 (Delivery Status Notifications, DSN) は RFC 1894 によって定義されています。