"email.header": 国際化されたヘッダー
************************************

**ソースコード:** Lib/email/header.py

======================================================================

このモジュールはレガシー("Compat32")な電子メールAPIの一部です。現在の
APIではヘッダのエンコードとデコードは "EmailMessage" クラスの辞書的な
APIによって透過的に処理されます。レガシーコードでの使用に加えて、この
モジュールは、ヘッダーをエンコードする際に使用される文字セットを完全に
制御する必要があるアプリケーションで役立ちます

この節の以降のテキストはモジュールの元々のドキュメントです。

**RFC 2822** は電子メールメッセージの形式を規定する基本規格です。これ
はほとんどの電子メールが ASCII 文字のみで構成されていたころ普及した
**RFC 822** 標準から発展したものです。 **RFC 2822** は電子メールがすべ
て 7-bit ASCII 文字のみから構成されていると仮定して作られた仕様です。

電子メールが世界中に普及するにつれ、国際化が進み、各言語固有の文字集合
を電子メールメッセージで使えるようになりました。 基本規格では今も 7 ビ
ットの ASCII 文字だけでの転送が求められるため、非 ASCII 文字を含む電子
メールを **RFC 2822** に準拠する形式にエンコードする方法を定めた RFC
が多数書かれています。 これには **RFC 2045**、**RFC 2046**、**RFC
2047**、**RFC 2231** などがあります。 "email" パッケージは
"email.header" と "email.charset" モジュールでこれらの規格をサポートし
ます。

*Subject* や *To* などの電子メールヘッダーに非 ASCII 文字を含めたい場
合は、"Header" クラスを使ってください。 "Message" オブジェクトのフィー
ルドには、文字列ではなく "Header" インスタンスをヘッダー値として代入し
ます。 "Header" クラスは "email.header" モジュールからインポートしてく
ださい。 例えば次のようにします。

   >>> from email.message import Message
   >>> from email.header import Header
   >>> msg = Message()
   >>> h = Header('p\xf6stal', 'iso-8859-1')
   >>> msg['Subject'] = h
   >>> msg.as_string()
   'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

ここでは *Subject* フィールドに非 ASCII 文字を含めています。 "Header"
インスタンスを作成し、エンコードに使う文字集合を渡すことで実現しました
。 その後 "Message" インスタンスをフラット化すると、*Subject* フィール
ドは正しく **RFC 2047** でエンコードされます。 MIME 対応のメールソフト
では、埋め込まれた ISO-8859-1 の文字を使ってこのヘッダーが表示されます
。

以下は "Header" クラスの説明です:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

   別の文字集合の文字列を含む MIME 準拠なヘッダを作成します。

   オプション引数 *s* はヘッダの値の初期値です。これが "None" の場合 (
   デフォルト)、ヘッダの初期値は設定されません。この値はあとから
   "append()" メソッドを呼びだすことによって追加することができます。
   *s* は "bytes" または "str" のインスタンスにできます。このセマンテ
   ィクスについては "append()" の項を参照してください。

   オプション引数 *charset* には 2 つの目的があります。ひとつは
   "append()" メソッドにおける *charset* 引数と同じものです。もうひと
   つは、これ以降 *charset* 引数を省略した "append()" メソッド呼び出し
   すべてにおける、デフォルト文字集合を決定するものです。コンストラク
   タに *charset* が与えられない場合 (デフォルト)、初期値の *s* および
   以後の "append()" 呼び出しにおける文字集合として "us-ascii" が使わ
   れます。

   行の最大長は *maxlinelen* で明示的に指定できます。 *Subject* など、
   *s* に含まれないフィールド名の長さを考慮して最初の行を短くするには
   、*header_name* にフィールド名を渡してください。 *maxlinelen* のデ
   フォルトは 78 です。 *header_name* のデフォルトは "None" で、この場
   合は長いヘッダーを折り返す際、最初の行でフィールド名の長さを考慮し
   ません。

   オプション引数 *continuation_ws* は **RFC 2822** 準拠の折り返し用余
   白文字で、ふつうこれは空白か、ハードタブ文字 (hard tab) である必要
   があります。ここで指定された文字は複数にわたる行の行頭に挿入されま
   す。 *continuation_ws* のデフォルト値は 1 つのスペース文字です。

   オプション引数 *errors* は、 "append()" メソッドにそのまま渡されま
   す。

   append(s, charset=None, errors='strict')

      この MIME ヘッダに文字列 *s* を追加します。

      オプション引数 *charset* がもし与えられた場合、これは "Charset"
      インスタンス ("email.charset" を参照) か、あるいは文字集合の名前
      でなければなりません。この場合は "Charset" インスタンスに変換さ
      れます。この値が "None" の場合 (デフォルト)、コンストラクタで与
      えられた *charset* が使われます。

      *s* は "bytes" または "str" のインスタンスです。 "bytes" のイン
      スタンスの場合、 *charset* はその文字列のエンコーディングであり
      、この文字セットでデコードできないときは "UnicodeError" が発生し
      ます。

      *s* が "str" のインスタンスの場合、 *charset* はその文字列の文字
      セットを決定するためのヒントとして使われます。

      いずれの場合でも、 **RFC 2822** 準拠のヘッダを **RFC 2047** の規
      則を用いて生成する際、文字列は指定された文字セットの出力コーデッ
      クを用いてエンコードされます。出力コーデックを用いて文字列がエン
      コードできないときは "UnicodeError" が発生します。

      オプションの *errors* は、 *s* がバイト文字列だった場合のデコー
      ド呼び出しに errors 引数として渡されます。

   encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

      メッセージヘッダを RFC に沿ったやり方でエンコードします。おそら
      く長い行は折り返され、非 ASCII 部分は base64 または quoted-
      printable エンコーディングで包含されるでしょう。

      省略可能な *splitchars* は、通常のヘッダーの折り返しで分割位置を
      決める際に優先する文字を含む文字列です。 これは **RFC 2822** の
      「上位の構文上の区切り」を大まかにサポートするものです。 指定さ
      れた文字の直後を分割位置として優先し、その優先順位は文字列内での
      並び順に従います。 スペースとタブもこの文字列に含められます。 こ
      れにより、分割する行に他の分割文字がない場合、スペースとタブのど
      ちらを分割位置として優先するかを指定できます。 "splitchars" は
      **RFC 2047** でエンコードされた行には影響しません。

      与えられた場合、*maxlinelen* はインスタンスの最大行長の値を上書
      きします。

      *linesep* は、折り返しヘッダの行を区切る文字を指定します。デフォ
      ルトではPythonアプリケーションコードに最も有用な値("\n")になりま
      すが、RFC準拠の行区切り文字でヘッダを生成するために "\r\n" を指
      定することができます。

      バージョン 3.2 で変更: *linesep* 引数が追加されました。

   "Header" クラスは、標準の演算子や組み込み関数をサポートするためのメ
   ソッドもいくつか提供しています。

   __str__()

      "Header" の内容に近い文字列を、行長の制限なしで返します。 すべて
      の部分を指定されたエンコーディングでデコードし、適切に結合します
      。 文字セットが "'unknown-8bit'" の部分は、"'replace'" エラーハ
      ンドラーを使って ASCII としてデコードします。

      バージョン 3.2 で変更: "'unknown-8bit'" 文字集合の処理が追加され
      ました。

   __eq__(other)

      このメソッドは、ふたつの "Header" インスタンスどうしが等しいかど
      うか判定するのに使えます。

   __ne__(other)

      このメソッドは、ふたつの "Header" インスタンスどうしが異なってい
      るかどうかを判定するのに使えます。

"email.header" モジュールは、以下の便利な関数も提供します。

email.header.decode_header(header)

   文字集合を変換せずにメッセージのヘッダをデコードします。ヘッダの値
   は *header* にあります。

   歴史的な理由から、この関数は次のいずれかを返します。

   1. ヘッダーの各部分をデコードした結果を含む "(decoded_bytes,
      charset)" ペアのリスト。 *decoded_bytes* は常に "bytes" インスタ
      ンスで、*charset* は次のいずれかです。

         * 指定された文字集合の名前を含む小文字の文字列。

         * エンコードされていないヘッダー部分では "None"。

   2. "(string, None)" ペアを一つ含む長さ 1 のリスト。 *string* は常に
      "str" インスタンスです。

   一部のデコードエラー (base64 のデコード例外など) が起きると、
   "email.errors.HeaderParseError" が送出されることがあります。

   以下に例を示します。

   >>> from email.header import decode_header
   >>> decode_header('=?iso-8859-1?q?p=F6stal?=')
   [(b'p\xf6stal', 'iso-8859-1')]
   >>> decode_header('unencoded_string')
   [('unencoded_string', None)]
   >>> decode_header('bar =?utf-8?B?ZsOzbw==?=')
   [(b'bar ', None), (b'f\xc3\xb3o', 'utf-8')]

   注釈:

     この関数は後方互換性のためだけに存在します。 新しいコードでは
     "email.headerregistry.HeaderRegistry" の使用を推奨します。

email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

   "decode_header()" によって返される 2要素タプルのリストから "Header"
   インスタンスを作成します。

   "decode_header()" はヘッダの値をとってきて、 "(decoded_string,
   charset)" という形式の 2要素タプルからなるリストを返します。ここで
   *decoded_string* はデコードされた文字列、 *charset* はその文字集合
   です。

   この関数は、そのようなペアのシーケンスを受け取り、"Header" インスタ
   ンスを返します。 省略可能な *maxlinelen*、*header_name*、
   *continuation_ws* は "Header" コンストラクタと同じです。

   注釈:

     この関数は後方互換性のためだけに存在し、新しいコードでの使用は推
     奨しません。
