"email.headerregistry": カスタムヘッダーオブジェクト
****************************************************

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

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

Added in version 3.6: [1]

ヘッダーは "str" のカスタマイズされたサブクラスで表現されます。 与えら
れたヘッダーを表現するために使用される特定のクラスは、ヘッダーが作成さ
れるときに有効な "policy" の "header_factory" で決定されます。 このセ
クションでは、email ライブラリが **RFC 5322** に準拠したメールメッセー
ジを扱うために実装している、特定の "header_factory" について説明します
。このヘッダーは、様々なヘッダータイプに対してカスタマイズされたヘッダ
ーオブジェクトを提供するだけでなく、アプリケーションが独自のカスタムヘ
ッダータイプを追加できるような拡張メカニズムも備えています。

"EmailPolicy" から派生したポリシーオブジェクトのいずれかを使用する場合
、すべてのヘッダーは "HeaderRegistry" によって生成され、最終的な基底ク
ラスとして "BaseHeader" を有します。 各ヘッダクラスには、ヘッダの種類
によって決まる追加のベースクラスがあります。 例えば、多くのヘッダーは
"UnstructuredHeader" というクラスをもうひとつの基底クラスとして持って
います。 ヘッダーに特化した第二のクラスは、ヘッダーの名前によって決定
され、 "HeaderRegistry" に格納されたルックアップテーブルを使用します。
これらすべては、典型的なアプリケーションプログラムに対しては透過的に管
理されますが、より複雑なアプリケーションで使用するためにデフォルトの動
作を変更するためのインタフェースが提供されています。

以下のセクションでは、まずヘッダーの基本クラスとその属性を説明し、次に
"HeaderRegistry" の動作を変更するための API、そして最後に構造化ヘッダ
ーからパースされたデータを表現するためのサポートクラスについて説明しま
す。

class email.headerregistry.BaseHeader(name, value)

   *name* と *value* は、"header_factory" の呼び出しから "BaseHeader"
   に渡されます。 ヘッダーオブジェクトの文字列としての値は、*value* を
   完全にデコードした文字列です。

   基底クラスは以下の読み出し専用属性を定義しています:

   name

      ヘッダーの名前(フィールドの':'の前の部分)。これは
      "header_factory" の *name* の呼び出しで渡された値と全く同じです;
      つまり、大文字・小文字が保持されます。

   defects

      パース中に見つかったRFCのコンプライアンス問題を報告する
      "HeaderDefect" インスタンスのタプルです。 email パッケージはコン
      プライアンスに関する問題を完全に検出するように努めています。 報
      告されるかもしれない欠陥の種類の議論については、 "errors" モジュ
      ールを参照してください。

   max_count

      このタイプのヘッダーで、同じ "name" を持つことができる最大数。
      値として "None" を指定すると、無制限になります。 この属性の
      "BaseHeader" の値は "None" です; 特殊な header クラスでは、必要
      に応じてこの値をオーバーライドすることが期待されます。

   "BaseHeader" は以下のメソッドも提供します。このメソッドはemail ライ
   ブラリのコードから呼び出され、一般にアプリケーションプログラムから
   は呼び出されません：

   fold(*, policy)

      ヘッダを *policy* に従って正しく折りたたむために必要な "linesep"
      文字を含む文字列を返します。 ヘッダには任意のバイナリデータを含
      めることができないため、 "cte_type" が "8bit" の場合は "7bit" と
      同じように扱われます。 もし "utf8" が "False" であれば、非ASCII
      データは **RFC 2047** でエンコードされます。

   "BaseHeader" 自身はヘッダーオブジェクトを生成するために使用すること
   はできません。このクラスは、それぞれの特殊化ヘッダーがヘッダーオブ
   ジェクトを生成するために協力するプロトコルを定義しています。 具体的
   には、 "BaseHeader" は "parse" という名前の "classmethod()" を特殊
   化されたクラスが提供することを要求しています。このメソッドは以下の
   ように呼び出されます:

      parse(string, kwds)

   "kwds" は、あらかじめ初期化されたキー "defects" を一つ含む辞書です
   。 "defects" の値は空のリストです。 "parse()" メソッドは、検出した
   欠陥をこのリストに追加する必要があります。 戻る際には、"kwds" 辞書
   に少なくとも "decoded"、"defects"、"parse_tree" の各キーの値が *な
   ければなりません*。 "decoded" はヘッダーの文字列値、つまりヘッダー
   値を完全にデコードした文字列にします。 "parse_tree" には、ヘッダー
   を解析して得た構文木を設定します。 "parse()" メソッドは、*string*
   にコンテンツ転送エンコーディングが適用された部分が含まれる可能性を
   考慮するとともに、エンコードされていないヘッダー値も解析できるよう
   、すべての有効な Unicode 文字を正しく扱う必要があります。

   その後、 "BaseHeader" の "__new__" がヘッダのインスタンスを生成し、
   "init" メソッドを呼び出します。 特殊クラスは、 "BaseHeader" が提供
   しない属性を設定したい場合にのみ "init" メソッドを提供する必要があ
   ります。 このような "init" メソッドは以下のようなものです。

      def init(self, /, *args, **kw):
          self._myattr = kw.pop('myattr')
          super().init(*args, **kw)

   つまり、特殊クラスが "kwds" の辞書に追加したものはすべて削除して処
   理し、 "kw" の残りの内容 (と "args") は "BaseHeader" の "init" メソ
   ッドに渡す必要があるのです。

class email.headerregistry.UnstructuredHeader

   "unstructured" ヘッダは **RFC 5322** におけるデフォルトのヘッダのタ
   イプです。指定された構文を持たないすべてのヘッダは、unstructuredと
   して扱われます。 構造化されていないヘッダの典型的な例は *Subject*
   ヘッダです。

   **RFC 5322** では、非構造化ヘッダーは ASCII 文字集合による任意のテ
   キストの並びです。 ただし、**RFC 2047** は、ヘッダー値の中で非
   ASCII テキストを ASCII 文字にエンコードする、**RFC 5322** と互換性
   のある仕組みを定めています。 エンコードされた語を含む *value* がコ
   ンストラクタに渡されると、"UnstructuredHeader" のパーサーは、非構造
   化テキストに関する **RFC 2047** の規則に従ってそれらを文字列に変換
   します。 パーサーは、一部の規格に準拠しないエンコードされた語につい
   ても、ヒューリスティックによってデコードを試みます。 その場合には欠
   陥が記録されます。 エンコードされた語やエンコードされていないテキス
   トに不正な文字がある場合なども同様です。

   このヘッダ型には追加の属性はありません。

class email.headerregistry.DateHeader

   **RFC 5322** は、電子メールヘッダー内の日付について厳密な形式を定め
   ています。 "DateHeader" のパーサーはその形式に加え、実際のメールで
   見かけるさまざまな変形も認識します。

   このヘッダ型は以下の属性も提供しています:

   datetime

      ヘッダー値を何らかの有効な日付形式として認識できた場合、この属性
      にはその日時を表す "datetime" インスタンスが入ります。 入力のタ
      イムゾーンが "-0000" (UTC だが送信元のタイムゾーン情報はないこと
      を示します) の場合、"datetime" は naive な "datetime" になります
      。 "+0000" を含む特定のタイムゾーンオフセットが見つかった場合、
      "datetime" は "datetime.timezone" でオフセットを記録した aware
      な "datetime" になります。

   ヘッダーの "decoded" 値は、"datetime" を **RFC 5322** の規則に従っ
   て書式化したものです。 つまり、次のように設定されます。

      email.utils.format_datetime(self.datetime)

   "DateHeader" を作成する際に、 *value* は "datetime" インスタンスで
   ある可能性があります。 これは、例えば、次のようなコードは有効であり
   、期待通りの動作をすることを意味します:

      msg['Date'] = datetime(2011, 7, 15, 21)

   これはnaive な "datetime" であるため、UTC タイムスタンプとして解釈
   され、結果として "-0000" というタイムゾーンを持つ値になります。 も
   っと便利なのは "utils" モジュールの "localtime()" 関数を使用するこ
   とです。

      msg['Date'] = utils.localtime()

   この例では、現在のタイムゾーンオフセットを使用して、日付ヘッダーを
   現在の時刻と日付に設定します。

class email.headerregistry.AddressHeader

   アドレスヘッダは最も複雑な構造のヘッダタイプの1つです。
   "AddressHeader" クラスは、あらゆるアドレスヘッダに対する汎用的なイ
   ンターフェースを提供します。

   このヘッダ型は以下の属性も提供しています:

   groups

      ヘッダー値に含まれるアドレスとグループをエンコードした "Group"
      オブジェクトのタプルです。 グループに属さないアドレスは、このリ
      ストでは "display_name" が "None" であるシングルアドレスの
      "Groups" として表現されます。

   addresses

      ヘッダー値に含まれる全ての個別アドレスをエンコードした "Address"
      オブジェクトのタプルです。 ヘッダ値にグループが含まれている場合
      、そのグループに含まれる個々のアドレスは、ヘッダ値でグループが出
      現した時点でリストに含まれます (つまり、アドレスのリストは一次元
      のリストに「フラット化」されます)。

   The "decoded" value of the header will have all encoded words
   decoded to a string.  "idna" encoded domain names are also decoded
   to a string.  The "decoded" value is set by joining the "str" value
   of the elements of the "groups" attribute with "', '".

   アドレスヘッダーの値の設定には、"Address" と "Group" オブジェクトを
   自由に組み合わせたリストを使えます。 "display_name" が "None" の
   "Group" オブジェクトは単独のアドレスとして解釈されます。 このため、
   元のヘッダーの "groups" 属性から得たリストを使えば、グループを保持
   したままアドレス一覧をコピーできます。

class email.headerregistry.SingleAddressHeader

   追加の属性を 1 つ持つ、"AddressHeader" の派生クラスです:

   address

      ヘッダー値で表された単一のアドレスです。 ヘッダー値に複数のアド
      レスが含まれる場合 (デフォルトの "policy" では RFC 違反です)、こ
      の属性にアクセスすると "ValueError" が発生します。

上記のクラスの多くには、"Unique" 版もあります (例えば
"UniqueUnstructuredHeader")。 違いは、"Unique" 版では "max_count" が 1
に設定されることだけです。

class email.headerregistry.MIMEVersionHeader

   *MIME-Version* ヘッダーの有効な値は実際には "1.0" だけです。 将来に
   備え、このヘッダークラスは他の有効なバージョン番号もサポートします
   。 バージョン番号が **RFC 2045** に照らして有効であれば、ヘッダーオ
   ブジェクトの以下の属性は "None" 以外の値になります。

   version

      バージョン番号 (文字列)、空白やコメントは除かれます。

   major

      メジャーバージョン番号 (整数)

   minor

      マイナーバージョン番号 (整数)

class email.headerregistry.ParameterizedMIMEHeader

   MIME ヘッダーはすべて接頭辞 "Content-" で始まります。 各ヘッダーに
   はそれぞれの値があり、対応するクラスの説明に記載されています。 また
   、共通形式の補助パラメータの一覧を持てるものもあります。 このクラス
   は、パラメータを持つすべての MIME ヘッダーの基底クラスです。

   params

      パラメータ名をパラメータ値に対応付ける辞書です。

      バージョン 3.15 で変更: "types.MappingProxyType" ではなく
      "frozendict" になりました。

class email.headerregistry.ContentTypeHeader

   *Content-Type* ヘッダを扱う "ParameterizedMIMEHeader" クラスです。

   content_type

      "maintype/subtype" 形式のコンテントタイプ文字列。

   maintype

   subtype

class email.headerregistry.ContentDispositionHeader

   *Content-Disposition* ヘッダを扱う "ParameterizedMIMEHeader" クラス
   です。

   content_disposition

      一般的に使われる有効な値は "inline" と "attachment" だけです。

class email.headerregistry.ContentTransferEncodingHeader

   *Content-Transfer-Encoding* ヘッダを扱います。

   cte

      有効な値は "7bit"、"8bit"、"base64"、"quoted-printable" です。詳
      細については **RFC 2045** を参照してください。

class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)

   これは "EmailPolicy" がデフォルトで使うファクトリです。
   "HeaderRegistry" は、*base_class* と自身のレジストリから取得した専
   用クラスを使って、ヘッダーインスタンスを作成するためのクラスを動的
   に構築します。 ヘッダー名がレジストリにない場合、*default_class* で
   指定されたクラスを専用クラスとして使います。 *use_default_map* が
   "True" (デフォルト) の場合、初期化時にヘッダー名からクラスへの標準
   の対応付けをレジストリにコピーします。 *base_class* は常に、生成さ
   れたクラスの "__bases__" 一覧の最後のクラスになります。

   デフォルトのマッピング:

      subject:
         UniqueUnstructuredHeader

      date:
         UniqueDateHeader

      resent-date:
         DateHeader

      orig-date:
         UniqueDateHeader

      sender:
         UniqueSingleAddressHeader

      resent-sender:
         SingleAddressHeader

      to:
         UniqueAddressHeader

      resent-to:
         AddressHeader

      cc:
         UniqueAddressHeader

      resent-cc:
         AddressHeader

      bcc:
         UniqueAddressHeader

      resent-bcc:
         AddressHeader

      from:
         UniqueAddressHeader

      resent-from:
         AddressHeader

      reply-to:
         UniqueAddressHeader

      mime-version:
         MIMEVersionHeader

      content-type:
         ContentTypeHeader

      content-disposition:
         ContentDispositionHeader

      content-transfer-encoding:
         ContentTransferEncodingHeader

      message-id:
         MessageIDHeader

   "HeaderRegistry" には以下のメソッドがあります:

   map_to_type(self, name, cls)

      *name* は対応付けるヘッダーの名前です。 レジストリ内では小文字に
      変換されます。 *cls* は専用クラスで、*base_class* と組み合わせて
      、*name* に一致するヘッダーをインスタンス化するクラスの作成に使
      われます。

   __getitem__(name)

      *name* ヘッダーの作成を担当するクラスを構築して返します。

   __call__(name, value)

      *name* に関連付けられた専用ヘッダークラスをレジストリから取得し
      ます (*name* がレジストリになければ *default_class* を使います)
      。 それを *base_class* と組み合わせてクラスを作成し、同じ引数リ
      ストを渡してそのコンストラクタを呼び出し、生成されたインスタンス
      を返します。

以下のクラスは、構造化ヘッダーから解析したデータの表現に使われます。
通常、アプリケーションからも、特定のヘッダーに代入する構造化された値の
作成に使えます。

class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)

   このクラスは電子メールのアドレスを表すのに使われます。アドレスの一
   般的な形式は:

      [display_name] <username@domain>

   もしくは:

      username@domain

   各部分は **RFC 5322** で定められた構文規則に従う必要があります。

   便利な方法として、*username* と *domain* の代わりに *addr_spec* を
   指定できます。 この場合、*username* と *domain* は *addr_spec* から
   解析されます。 *addr_spec* は RFC に従って正しく引用符を付けた文字
   列でなければならず、そうでなければ "Address" はエラーを送出します。
   Unicode 文字も使用でき、直列化時に適切にエンコードされます。 ただし
   、RFC に従い、アドレスのユーザー名部分では Unicode は許可 *されませ
   ん*。

   display_name

      アドレスの表示名部分で、引用符はすべて取り除かれます。 アドレス
      に表示名がなければ、空文字列になります。

   username

      アドレスの "username" 部分、クォートは取り除かれます。

   domain

      アドレスの "domain" 部分。

   addr_spec

      アドレスの "username@domain" 部分で、表示名のないアドレス (上記
      の 2 番目の形式) として使えるよう正しく引用符が付けられます。 こ
      の属性は変更できません。

   __str__()

      オブジェクトの "str" 値は、**RFC 5322** の規則に従って引用符を付
      けたアドレスですが、非 ASCII 文字にコンテンツ転送エンコーディン
      グは適用されません。

   SMTP (**RFC 5321**) をサポートするため、"Address" は一つの特殊な場
   合を扱います。 "username" と "domain" が両方とも空文字列 (または
   "None") の場合、"Address" の文字列値は "<>" になります。

class email.headerregistry.Group(display_name=None, addresses=None)

   このクラスはアドレスグループを表すのに使われます。アドレスグループ
   の一般的な形式は:

      display_name: [address-list];

   グループと単独のアドレスが混在する一覧を扱いやすくするため、"Group"
   でグループに属さない単独のアドレスを表すこともできます。 その場合、
   *display_name* を "None" にし、*addresses* にそのアドレスだけを含む
   リストを渡します。

   display_name

      グループの "display_name" です。 値が "None" で、"addresses" に
      "Address" がちょうど一つある場合、その "Group" はグループに属さ
      ない単独のアドレスを表します。

   addresses

      グループ内のアドレスを表す "Address" オブジェクトのタプルです。
      空の場合もあります。

   __str__()

      "Group" の "str" 値は **RFC 5322** に従って書式化されますが、非
      ASCII 文字にコンテンツ転送エンコーディングは適用されません。
      "display_name" が "None" で、"addresses" リストに "Address" が一
      つだけある場合、"str" 値はその "Address" の "str" 値と同じになり
      ます。

-[ 脚注 ]-

[1] 当初は 3.3 で *暫定モジュール* として追加されました。
