5. インポートシステム
*********************

ある 1 つの *module* にある Python コードから他のモジュールを *インポ
ート* することで、そこにあるコードへアクセスできるようになります。
"import" 文はインポート機構を動かす最も一般的な方法ですが、それが唯一
の方法ではありません。 "importlib.import_module()" や組み込みの
"__import__()" といった関数を使っても、インポート機構を動かすことがで
きます。

"import" 文は 2 つの処理を連続して行っています; ある名前のモジュールを
探し、その検索結果をローカルスコープの名前に束縛します。 "import" 文の
検索処理は、適切な引数で "__import__()" 関数を呼び出すこととして定義さ
れています。 "__import__()" の戻り値は "import" 文の名前束縛処理の実行
で使われます。名前束縛処理の厳密な詳細は "import" 文を参照してください
。

"__import__()" を直接呼び出すとモジュールの検索のみが行われ、見つかっ
た場合、モジュールの作成処理が行われます。親パッケージのインポートや
("sys.modules" を含む) 様々なキャッシュの更新などの副作用は起きるかも
しれませんが、 "import" 文のみが名前束縛処理を行います。

"import" 文が実行されるときには、標準の組み込み関数 "__import__()" が
呼ばれます。インポートシステムを呼び出すその他の
("importlib.import_module()" 関数のような)  メカニズムは、
"__import__()" の呼び出しをバイパスして独自のインポート・セマンティク
スを実装している可能性があります。

モジュールが初めてインポートされるとき、 Python はそのモジュールを検索
し、見付かった場合、モジュールオブジェクトを作成し、初期化します [1]
。その名前のモジュールが見付からなかった場合、 "ModuleNotFoundError"
が送出されます。 Python には、インポート機構が実行されたときに名前から
モジュールを検索する様々な戦略が実装されています。これらの戦略は、これ
以降の節で解説される様々なフックを使って、修正したり拡張したりできます
。

バージョン 3.3 で変更: インポートシステムが **PEP 302** の第 2 フェー
ズの完全な実装へ更新されました。もはや暗黙的なインポート機構はありませ
ん - インポート機構全体は "sys.meta_path" を通して公開されています。加
えて、ネイティブの名前空間パッケージのサポートは実装されています
(**PEP 420** を参照) 。


5.1. "importlib"
================

"importlib" モジュールはインポート機構とやり取りするための便利な API
を提供します。例えば "importlib.import_module()" は、インポート機構を
実行するための組み込みの "__import__()" よりもシンプルで推奨される API
を提供します。より詳細なことは "importlib" ライブラリのドキュメントを
参照してください。


5.2. パッケージ
===============

Python にはモジュールオブジェクトの種類は 1 種類しかなく、 Python 、 C
、それ以外のもののどれで実装されているかに関係なく、すべてのモジュール
はこの種類になります。モジュールの組織化を助け、名前階層を提供するため
に、 Python には *パッケージ* という概念があります。

パッケージはファイルシステムのディレクトリ、モジュールはディレクトリに
あるファイルと考えることができますが、パッケージやモジュールはファイル
システムから生まれる必要はないので、この比喩を額面通りに受け取ってはい
けません。この文書の目的のために、ディレクトリとファイルという便利な比
喩を使うことにします。ファイルシステムのディレクトリのように、パッケー
ジは階層構造を成し、通常のモジュールだけでなく、サブパッケージを含むこ
ともあります。

すべてのパッケージはモジュールですが、すべてのモジュールがパッケージと
は限らないことを心に留めておくのが重要です。もしくは他の言い方をすると
、パッケージは単なる特別な種類のモジュールであると言えます。特に、
"__path__" 属性を持つ任意のモジュールはパッケージと見なされます。

すべてのモジュールは名前を持ちます。Python の属性アクセスの文法と同様
に、サブパッケージの名前は親パッケージ名とドット記号で区切られます。し
たがって、"email" という名前のパッケージや、それが含む "email.mime" と
いう名前のサブパッケージ、さらにそれに含まれる "email.mime.text" と言
う名前のモジュールを考えることができます。


5.2.1. 通常のパッケージ
-----------------------

Python では、 *通常のパッケージ* と *名前空間パッケージ* の 2 種類のパ
ッケージが定義されています。通常のパッケージは Python 3.2 以前から存在
する伝統的なパッケージです。典型的な通常のパッケージは "__init__.py"
ファイルを含むディレクトリとして実装されます。通常のパッケージがインポ
ートされたとき、この "__init__.py" ファイルが暗黙的に実行され、それで
定義しているオブジェクトがパッケージ名前空間にある名前に束縛されます。
"__init__.py" ファイルは、他のモジュールに書ける Python コードと同じも
のを含むことができ、モジュールがインポートされたときに Python はモジュ
ールに属性を追加したりします。

例えば、以下のようなファイルシステム配置は、3 つのサブパッケージを持つ
最上位の "parent" パッケージを定義します:

   parent/
       __init__.py
       one/
           __init__.py
       two/
           __init__.py
       three/
           __init__.py

"parent.one" をインポートすると暗黙的に "parent/__init__.py" と
"parent/one/__init__.py" が実行されます。その後に "parent.two" もしく
は "parent.three" をインポートすると、それぞれ
"parent/two/__init__.py" や "parent/three/__init__.py" が実行されます
。


5.2.2. 名前空間パッケージ
-------------------------

名前空間パッケージは様々な *ポーション* を寄せ集めたもので、それぞれの
ポーションはサブパッケージを親パッケージに提供します。ポーションはファ
イルシステムの別々の場所にあることもあります。ポーションは、 zip ファ
イルの中やネットワーク上や、それ以外のインポート時に Python が探すどこ
かの場所で見つかることもあります。名前空間パッケージはファイルシステム
上のオブジェクトに対応することもあるし、そうでないこともあります; それ
らは実際の実体のない仮想モジュールです。

名前空間パッケージは、  "__path__" 属性に普通のリストは使いません。そ
の代わりに独自の iterable 型を使っていて、ポーションの親パッケージのパ
ス (もしくは最上位パッケージのための "sys.path") が変わった場合、その
パッケージでの次のインポートの際に、新たに自動でパッケージポーションを
検索します。

名前空間パッケージには "parent/__init__.py" ファイルはありません。それ
どころか、異なるポーションがそれぞれ提供する複数の "parent" ディレクト
リがインポート検索の際に見つかることもあります。したがって
"parent/one" は物理的に "parent/two" の隣りにあるとは限りません。その
場合、そのパッケージかサブパッケージのうち 1 つがインポートされたとき
、Python は最上位の "parent" パッケージのための名前空間パッケージを作
成します。

名前空間パッケージの仕様については **PEP 420** も参照してください。


5.3. 検索
=========

検索を始めるためには、 Python はインポートされるモジュール (もしくはパ
ッケージですが、ここでの議論の目的においてはささいな違いです) の *完全
修飾* 名を必要とします。この名前は、 "import" 文の様々な引数や
"importlib.import_module()" および "__import__()" 関数のパラメータから
得られます。

この名前はインポート検索の様々なフェーズで使われ、これは例えば
"foo.bar.baz" のようなドットで区切られたサブモジュールへのパスだったり
します。この場合、 Python は最初に "foo" を、次に "foo.bar" 、そして最
後に "foo.bar.baz" をインポートしようとします。中間のいずれかのインポ
ートに失敗した場合は、 "ModuleNotFoundError" が送出されます。


5.3.1. モジュールキャッシュ
---------------------------

インポート検索で最初に調べる場所は "sys.modules" です。このマッピング
は、中間のパスを含む、これまでにインポートされたすべてのモジュールのキ
ャッシュを提供します。なので "foo.bar.baz" がインポート済みの場合、
"sys.modules" は "foo" 、 "foo.bar" 、 "foo.bar.baz" のエントリーを含
みます。それぞれのキーはその値として対応するモジュールオブジェクトを持
ちます。

インポートではモジュール名は "sys.modules" から探され、存在した場合は
、対応する値がインポートされるべきモジュールであり、この処理は完了しま
す。しかし値が "None" だった場合、 "ModuleNotFoundError" が送出されま
す。モジュール名が見付からなかった場合は、 Python はモジュールの検索を
続けます。

"sys.modules" は書き込み可能です。キーの削除は対応するモジュールを破壊
しない (他のモジュールがそのモジュールへの参照を持っている) かもしれま
せんが、指定されたモジュールのキャッシュされたエントリーを無効にし、そ
れが次にインポートされたとき Python にそのモジュールを改めて検索させる
ことになります。キーを "None" に対応付けることもできますが、次にそのモ
ジュールがインポートされるときに "ModuleNotFoundError" となってしまい
ます。

たとえモジュールオブジェクトへの参照を保持しておいて、 "sys.modules"
にキャッシュされたエントリーを無効にし、その指定したモジュールを再イン
ポートしたとしても、 2 つのモジュールオブジェクトは同じでは *ない* こ
とに注意してください。それとは対照的に、 "importlib.reload()" は *同じ
* モジュールオブジェクトを再利用し、モジュールのコードを再実行すること
で単にモジュールの内容を再初期化するだけです。


5.3.2. ファインダーとローダー
-----------------------------

"sys.modules" に指定されたモジュールが見つからなかった場合は、 Python
のインポートプロトコルが起動され、モジュールを見つけロードします。この
プロトコルは 2 つの概念的なオブジェクト、 *ファインダー* と *ローダー*
から成ります。ファインダーの仕事は、知っている戦略を使って指定されたモ
ジュールを見つけられるかどうか判断することです。両方のインターフェース
を実装しているオブジェクトは *インポーター* と呼ばれます - インポータ
ーは要求されたモジュールがロードできると分かったとき、自分自身を返しま
す。

Python にはデフォルトのファインダーとインポーターがいくつかあります。
1 つ目のものは組み込みモジュールの見つけ方を知っていて、 2 つ目のもの
は凍結されたモジュール (訳注: freeze ツールで処理されたモジュールのこ
と。 プログラミング FAQ の「どうしたら Python スクリプトからスタンドア
ロンバイナリを作れますか？」の項目を参照) の見つけ方を知っています。 3
つ目のものは *インポートパス* からモジュールを探します。 *インポートパ
ス* はファイルシステムのパスや zip ファイルの位置を示すリストです。こ
のリストは、 URL で特定できるもののような、位置を示すことのできる任意
のリソースの検索にまで拡張することもできます。

インポート機構は拡張可能なので、モジュール検索の範囲とスコープを拡張す
るために新しいファインダーを付け加えることができます。

ファインダーは実際にはモジュールをロードしません。指定されたモジュール
が見つかった場合、ファインダーは *module spec* (モジュール仕様)、すな
わちモジュールのインポート関連の情報をカプセル化したものを返します。モ
ジュールのロード時にインポート機構はそれを利用します。

次の節では、インポート機構を拡張するための新しいファインダーやローダー
の作成と登録を含め、ファインダーとローダーのプロトコルについてより詳し
く解説します。

バージョン 3.4 で変更: Python の以前のバージョンでは、ファインダーは直
接 *ローダー* を返していましたが、現在はローダーを *含む* モジュール仕
様を返します。ローダーはインポート中はまだ使われていますが、責任は減り
ました。


5.3.3. インポートフック
-----------------------

インポート機構は拡張可能なように設計されています; その主となる仕組みは
*インポートフック* です。インポートフックには 2 種類あります: *メタフ
ック* と *インポートパスフック* です。

メタフックはインポート処理の最初、 "sys.modules" キャッシュの検索以外
のインポート処理より前に呼び出されます。これにより、 "sys.path" の処理
や凍結されたモジュールや組み込みのモジュールでさえも、メタフックで上書
きすることができます。メタフックは以下で解説するように、
"sys.meta_path" に新しいファインダーオブジェクトを追加することで登録さ
れます。

インポートパスフックは、 "sys.path" (もしくは "package.__path__") の処
理の一部として、対応するパス要素を取り扱うところで呼び出されます。イン
ポートパスフックは以下で解説するように、新しい呼び出し可能オブジェクト
を "sys.path_hooks" に追加することで登録されます。


5.3.4. メタパス
---------------

指定されたモジュールが "sys.modules" に見つからなかったとき、 Python
は次にメタパス・ファインダー・オブジェクトが格納されている
"sys.meta_path" を検索します。指定されたモジュールを扱うことができるか
どうかを調べるために、各ファインダーに問い合わせを行います。メタパス・
ファインダーには、名前とインポートパスと (オプションの) ターゲットモジ
ュールの 3 つの引数を取る "find_spec()" という名前のメソッドが実装され
ていなければいけません。メタパス・ファインダーでは、指定されたモジュー
ルを扱えるかどうかを判定するための戦略は任意のものを使って構いません。

meta path finder が指定されたモジュールの扱い方を知っている場合は、フ
ァインダは spec オブジェクトを返します。指定されたモジュールを扱えない
場合は "None" を返します。 "sys.meta_path" に対する処理が spec を返さ
ずにリストの末尾に到達してしまった場合は、 "ModuleNotFoundError" を送
出します。その他の送出された例外はそのまま呼び出し元に伝播され、インポ
ート処理を異常終了させます。

メタパス・ファインダーの "find_spec()" メソッドは 2 つまたは 3 つの引
数を渡して呼び出します。1 つ目の引数はインポートされるモジュールの完全
修飾名で、例えば "foo.bar.baz" などです。2 つ目の引数はモジュールの検
索で使われるパスです。最上位のモジュールでは 2 つ目の引数は "None" に
しますが、サブモジュールやサブパッケージでは 2 つ目の引数は親パッケー
ジの "__path__" 属性の値です。適切な "__path__" 属性にアクセスできなか
った場合は、 "ModuleNotFoundError" が送出されます。3 つ目の引数は、あ
とでロードされるターゲットとなる既存のモジュールオブジェクトです。イン
ポートシステムはリロードの間だけターゲットモジュール をセットします。

メタパスは、1 回のインポート要求で複数回走査される可能性があります。例
えば、関係するモジュールがどれもまだキャッシュされていないとしたときに
"foo.bar.baz" をインポートすると、最初は各メタパス・ファインダー
("mpf") に対して "mpf.find_spec("foo", None, None)" を呼び出して、最上
位のインポート処理を行います。"foo" がインポートされた後に、
"mpf.find_spec("foo.bar", foo.__path__, None)" を呼び出していく 2 回目
のメタパスの走査が行われ、"foo.bar" がインポートされます。"foo.bar" の
インポートまで行われたら、最後の走査で "mpf.find_spec("foo.bar.baz",
foo.bar.__path__, None)" を呼び出していきます。

あるメタパス・ファインダーは最上位のインポートのみサポートしています。
これらのインポーターは、2 つ目の引数に "None" 以外のものが渡されたとき
、常に "None" を返します。

Python のデフォルトの "sys.meta_path" は 3 つのパスファインダーを持っ
ています。組み込みモジュールのインポートの方法を知っているもの、凍結さ
れたモジュールのインポートの方法を知っているもの、 *インポートパス* か
らのモジュールのインポートの方法を知っているもの (つまり *パスベース・
ファインダー*) があります。

バージョン 3.4 で変更: メタパス・ファインダーの "find_module()" メソッ
ドは "find_spec()" に置き換えられました。 "find_module()" メソッドは非
推奨 (deprecated) です。前者のメソッドは今でも変更なしに動きますが、イ
ンポート機構はファインダーが "find_spec()" を実装していない場合にのみ
それを試します。

バージョン 3.10 で変更: インポート機構が "find_module()" を使用した場
合、"ImportWarning" が発生します。


5.4. ロード
===========

モジュール仕様が見つかった場合、インポート機構はモジュールをロードする
時にそれ (およびそれに含まれるローダー) を使います。これは、インポート
のロード部分で起こることの近似です:

   module = None
   if spec.loader is not None and hasattr(spec.loader, 'create_module'):
       # It is assumed 'exec_module' will also be defined on the loader.
       module = spec.loader.create_module(spec)
   if module is None:
       module = ModuleType(spec.name)
   # The import-related module attributes get set here:
   _init_module_attrs(spec, module)

   if spec.loader is None:
       # unsupported
       raise ImportError
   if spec.origin is None and spec.submodule_search_locations is not None:
       # namespace package
       sys.modules[spec.name] = module
   elif not hasattr(spec.loader, 'exec_module'):
       module = spec.loader.load_module(spec.name)
       # Set __loader__ and __package__ if missing.
   else:
       sys.modules[spec.name] = module
       try:
           spec.loader.exec_module(module)
       except BaseException:
           try:
               del sys.modules[spec.name]
           except KeyError:
               pass
           raise
   return sys.modules[spec.name]

以下の詳細に注意してください:

   * "sys.modules" の中に与えられた名前を持つ既存のモジュールオブジェ
     クトがあるなら、 import は既にそれを返しているでしょう。

   * モジュールは、ローダーがモジュールコードを実行する前に
     "sys.modules" に存在しています。 モジュールコードが (直接的または
     間接的に) 自分自身をインポートする可能性があるので、これは重要で
     す; モジュールを "sys.modules" に追加することで、最悪のケースでは
     無限の再帰が、そして最良のケースでは複数回のロードが、前もって防
     止されます。

   * ロード処理に失敗した場合、その失敗したモジュールは -- そして、そ
     のモジュールだけが -- "sys.modules" から取り除かれます。
     "sys.modules" キャッシュに既に含まれていたすべてのモジュールと、
     副作用としてロードに成功したすべてのモジュールは、常にキャッシュ
     に残されます。これはリロードとは対照的で、リロードの場合は失敗し
     たモジュールも "sys.modules" に残されます。

   * 後のセクション で要約されるように、モジュールが作られてから実行さ
     れるまでの間にインポート機構はインポート関連のモジュール属性を設
     定します (上記擬似コード例の "_init_module_attrs")。

   * モジュール実行はモジュールの名前空間が構築されるロードの重要な瞬
     間です。実行はローダーに完全に委任され、ローダーは何をどのように
     構築するかを決定することになります。

   * ロードの間に作成されて exec_module() に渡されたモジュールは、イン
     ポートの終わりに返されるものとは異なるかもしれません [2]。

バージョン 3.4 で変更: インポートシステムはローダーの定型的な責任を引
き継ぎました。これらは以前は "importlib.abc.Loader.load_module()" メソ
ッドによって実行されました。


5.4.1. ローダー
---------------

モジュールローダーは、ロードの重要な機能であるモジュール実行機能を提供
します。インポート機構は、実行しようとするモジュールオブジェクトを単一
の引数として "importlib.abc.Loader.exec_module()" メソッドを呼び出しま
す。 "importlib.abc.Loader.exec_module()" から返された任意の値は無視さ
れます。

ローダーは以下の仕様を満たしていなければいけません:

   * モジュールが (組み込みモジュールや動的に読み込まれる拡張モジュー
     ルではなくて) Python モジュールだった場合、ローダーはモジュールの
     グローバル名前空間 ("module.__dict__") で、モジュールのコードを実
     行すべきです。

   * "exec_module()" の呼び出し中に "ImportError" 以外の例外が送出され
     、伝播されてきたとしても、モジュールをロードできない場合は
     "ImportError" を送出すべきです。

多くの場合、ファインダーとローダーは同じオブジェクトで構いません; その
ような場合では "find_spec()" メソッドは単に "self" (訳注: オブジェクト
自身) を返すだけです。

モジュールローダーは、 "create_module()" メソッドを実装することでロー
ド中にモジュールオブジェクトを作成することを選択できます。このメソッド
は、モジュール仕様を引数に取って、ロード中に使う新しいモジュールオブジ
ェクトを返します。 "create_module()" はモジュールオブジェクトに属性を
設定する必要はありません。もしこのメソッドが "None" を返すなら、インポ
ート機構は新しいモジュールを自身で作成します。

バージョン 3.4 で追加: ローダーの "create_module()" メソッド。

バージョン 3.4 で変更: "load_module()" メソッドは "exec_module()" によ
って置き換えられ、インポート機構がロードのすべての定型的な処理を引き受
けました。既存のローダーとの互換性のため、もしローダーに
"load_module()" メソッドが存在し、かつローダーが "exec_module()" を実
装していなければ、インポート機構はローダーの "load_module()" メソッド
を使います。しかし、 "load_module()" は deprecated であり、ローダーは
代わりに "exec_module()" を実装すべきです。"load_module()" メソッドは
、モジュールを実行することに加えて上記で説明されたすべての定型的なロー
ド機能を実施しなければなりません。同じ制約が適用されます。以下は追加の
明確化です:

   * "sys.modules" に与えられた名前のモジュールが存在している場合、ロ
     ーダーはその既存のモジュールを使わなければいけません。 (そうしな
     いと "importlib.reload()" は正しく動かないでしょう。) 指定された
     モジュールが "sys.modules" に存在しない場合、ローダーは新しいモジ
     ュールオブジェクトを作成し、 "sys.modules" に追加しなければいけま
     せん。

   * 無限の再帰または複数回のロードを防止するために、ローダーがモジュ
     ールコードを実行する前にモジュールは "sys.modules" に存在しなけれ
     ばなりません (*must*)。

   * ロード処理に失敗した場合、ローダーは "sys.modules" に追加したモジ
     ュールを取り除かなければいけませんが、それはロードに失敗したモジ
     ュール **のみ** を、そのモジュールがローダー自身に明示的にロード
     された場合に限り、除去しなければなりません。

バージョン 3.5 で変更: "exec_module()" が定義されていて
"create_module()" が定義されていない場合、 "DeprecationWarning" が送出
されるようになりました。

バージョン 3.6 で変更: "exec_module()" が定義されていて
"create_module()" が定義されていない場合、 "ImportError" が送出される
ようになりました。

バージョン 3.10 で変更: "load_module()" を使用すると "ImportWarning"
が発生します。


5.4.2. サブモジュール
---------------------

サブモジュールをロードするのにどのようなメカニズム (例えば、
"importlib" API 、 "import" または "import-from" ステートメント、また
はビルトイン関数の "__import__") が使われた場合でも、バインディングは
サブモジュールオブジェクトを親モジュールの名前空間に配置します。例えば
、もしパッケージ "spam" がサブモジュール "foo" を持っていた場合、
"spam.foo" をインポートした後は "spam" は値がサブモジュールに束縛され
た属性 "foo" を持ちます。以下のディレクトリ構造を持っているとしましょ
う:

   spam/
       __init__.py
       foo.py

そして "spam/__init__.py" は以下のようになっているとします:

   from .foo import Foo

このとき、以下を実行することにより "spam" モジュールの中に "foo" と
"Foo" に束縛された名前が置かれます:

   >>> import spam
   >>> spam.foo
   <module 'spam.foo' from '/tmp/imports/spam/foo.py'>
   >>> spam.Foo
   <class 'spam.foo.Foo'>

Python の慣れ親しんだ名前束縛ルールからするとこれは驚きかもしれません
が、それは実際インポートシステムの基本的な機能です。不変に保たなければ
ならないのは (上記のインポートの後などで) "sys.modules['spam']" と
"sys.modules['spam.foo']" が存在する場合、後者が前者の "foo" 属性とし
て存在しなければならないということです。


5.4.3. モジュール仕様
---------------------

インポート機構は、インポートの間 (特にロードの前) に、個々のモジュール
についてのさまざまな情報を扱います。情報のほとんどはすべてのモジュール
で共通です。モジュール仕様の目的は、このインポート関連の情報をモジュー
ルの単位でカプセル化することです。

インポートの際にモジュール仕様を使うことは、インポートシステムコンポー
ネント間、例えばモジュール仕様を作成するファインダーとそれを実行するロ
ーダーの間で状態を転送することを可能にします。最も重要なのは、それによ
ってインポート機構がロードの定型的な作業を実行できるようになるというこ
とです。これに対して、モジュール仕様なしではローダがその責任を担ってい
ました。

モジュール仕様は、モジュールオブジェクトの "__spec__" 属性として公開さ
れます。 モジュール仕様の内容の詳細については "ModuleSpec" を参照して
ください。

バージョン 3.4 で追加.


5.4.4. インポート関連のモジュール属性
-------------------------------------

インポート機構はロードの間、モジュールの仕様に基づいて、ローダーがモジ
ュールが実行する前に以下の属性を書き込みます。

__name__

   "__name__" 属性はモジュールの完全修飾名に設定されなければなりません
   。この名前を利用してインポートシステムでモジュールを一意に識別しま
   す。

__loader__

   "__loader__" 属性はモジュールロード時にインポート機構が使用したロー
   ダーオブジェクトに設定されなければなりません。この属性は普通は内省
   用のものですが、ローダー固有の追加機能のために用いることが出来ます
   。例えばローダー関連のデータの取得です。

__package__

   モジュールの "__package__" 属性は設定されなければなりません。値は文
   字列でなければなりませんが、"__name__" と同じ値でも構いません。モジ
   ュールがパッケージの場合、"__package__" の値はその "__name__" でな
   ければなりません。モジュールがパッケージでない場合、トップレベルの
   モジュールでは "__package__" は空の文字列、サブモジュールでは親のパ
   ッケージ名でなければなりません。詳細は **PEP 366** を参照してくださ
   い。

   この属性は **PEP 366** で定義されているように、メインモジュールから
   の明示的な相対インポートを計算するために、 "__name__" の代わりに使
   用されます。 この属性は "__spec__.parent" と同じ値を持つことを要求
   されます。

   バージョン 3.6 で変更: "__package__" の値が "__spec__.parent" と同
   じ値を持つことを要求されるようになりました。

__spec__

   "__spec__" 属性はモジュールロード時に使用されたモジュールスペックに
   設定されなければなりません。 "__spec__" を適切に設定すると インター
   プリタ起動中に初期化されるモジュール にも同様に適用されます。 例外
   は "__main__" で、"__spec__" は 場合によっては None に設定されます
   。

   "__package__" が定義されていないときは "__spec__.parent" がフォール
   バックとして使われます。

   バージョン 3.4 で追加.

   バージョン 3.6 で変更: "__package__" が定義されていないときに
   "__spec__.parent" がフォールバックとして使われるようになりました。

__path__

   モジュールが (通常のまたは名前空間) パッケージの場合、モジュールオ
   ブジェクトの  "__path__" 属性が設定される必要があります。値はイテレ
   ート可能でなければなりませんが、"__path__" に意味がない場合は空でも
   構いません。"__path__" が空でない場合、イテレート時に文字列を生成し
   なければなりません。"__path__" のセマンティクスの詳細は  下記 の通
   りです。

   パッケージでないモジュールは "__path__" 属性を持ってはいけません。

__file__

__cached__

   "__file__" はオプションです。もし設定されるならば、この属性の値は文
   字列でなければなりません。もしそのような属性が意味を持たない場合 (
   例えばモジュールがデータベースからロードされた場合) インポートシス
   テムは "__file__" を未設定のままにしても構いません。

   もし "__file__" を設定するなら、 "__cached__" 属性もコードのコンパ
   イルされたバージョンのどれか (例えば、バイトコンパイルされたファイ
   ル) へのパスに設定することが適切でしょう。この属性を設定するにあた
   ってファイルが存在する必要はありません; パスは、単にコンパイルされ
   たファイルが存在するかもしれない場所を示しているだけです (**PEP
   3147** を参照)。

   "__file__" が設定されない場合にも "__cached__" を設定することは適切
   です。しかし、そのシナリオはかなり変則的です。究極的には、ローダー
   とは "__file__" と "__cached__" のどちらかまたは両方を利用するもの
   です。したがって、もしローダーがキャッシュされたモジュールからロー
   ドする一方でファイルからはロードしないなら、その変則的なシナリオは
   適切でしょう。


5.4.5. module.__path__
----------------------

定義より、モジュールに "__path__" 属性があれば、そのモジュールはパッケ
ージとなります。

パッケージの "__path__" 属性は、そのサブパッケージのインポート中に使わ
れます。インポート機構の内部では、それは "sys.path" とほとんど同じよう
に機能します。つまり、インポート中にモジュールを探す場所のリストを提供
します。しかし、一般的に "__path__" は "sys.path" よりも制約が強いです
。

"__path__" は文字列の iterable でなければいけませんが、空でも構いませ
ん。 "sys.path" と同じ規則がパッケージの "__path__" にも適用され、パッ
ケージの "__path__" を走査するときに (後で解説する) "sys.path_hooks"
が考慮に入れられます。

パッケージの "__init__.py" ファイルは、パッケージの "__path__" 属性を
設定もしくは変更することがあり、これが **PEP 420** 以前の名前空間パッ
ケージの典型的な実装方法でした。 **PEP 420** の採択により、もはや名前
空間パッケージは、 "__path__" を操作するコードだけを含む "__init__.py"
ファイルを提供する必要がなくなりました;インポート機構は、名前空間パッ
ケージに対し自動的に適切な "__path__" をセットします。


5.4.6. モジュールの repr
------------------------

デフォルトでは、すべてのモジュールは利用可能な repr を持っています。た
だしこれは、これまでに説明した属性の設定内容に依存しており、モジュール
仕様によってモジュールオブジェクトの repr をより明示的に制御することが
できます。

もしモジュールが仕様 ("__spec__") を持っていれば、インポート機構はそこ
から repr を生成しようとします。もしそれが失敗するか、または仕様が存在
しなければ、インポートシステムはモジュールで入手可能なあらゆる情報を使
ってデフォルトの repr を構築します。それは "module.__name__",
"module.__file__", "module.__loader__" を (足りない情報についてはデフ
ォルト値を使って補いながら) repr への入力として使おうと試みます。

これが使われている正確な規則です:

   * モジュールが "__spec__" 属性を持っていれば、仕様に含まれる情報が
     repr を生成するために使われます。 "name", "loader", "origin",
     "has_location" 属性が参照されます。

   * モジュールに "__file__" 属性がある場合は、モジュールの repr の一
     部として使われます。

   * モジュールに "__file__" はないが "__loader__" があり、その値が
     "None" ではない場合は、ローダーの repr がモジュールの repr の一部
     として使われます。

   * そうでなければ、単にモジュールの "__name__" を repr の中で使いま
     す。

バージョン 3.4 で変更: "loader.module_repr()" の使用は非推奨
(deprecated) です。インポート機構によりモジュール仕様がモジュール repr
を生成するために使用されるようになりました。Python 3.3 との後方互換性
のために、ローダーの "module_repr()" メソッドが定義されていたら、モジ
ュール repr を生成するために上記のいずれかのアプローチを試す前にそのメ
ソッドが呼ばれます。ただし、このメソッドは deprecated です。

バージョン 3.10 で変更: "module_repr()" の呼び出しは、モジュールの
"__spec__" 属性のアクセスに失敗した後、かつ、"__file__" 属性を試す前の
タイミングで行われるようになりました。Python 3.12 では "module_repr()"
は使用されなくなる予定です。


5.4.7. キャッシュされたバイトコードの無効化
-------------------------------------------

Before Python loads cached bytecode from a ".pyc" file, it checks
whether the cache is up-to-date with the source ".py" file. By
default, Python does this by storing the source's last-modified
timestamp and size in the cache file when writing it. At runtime, the
import system then validates the cache file by checking the stored
metadata in the cache file against the source's metadata.

Python also supports "hash-based" cache files, which store a hash of
the source file's contents rather than its metadata. There are two
variants of hash-based ".pyc" files: checked and unchecked. For
checked hash-based ".pyc" files, Python validates the cache file by
hashing the source file and comparing the resulting hash with the hash
in the cache file. If a checked hash-based cache file is found to be
invalid, Python regenerates it and writes a new checked hash-based
cache file. For unchecked hash-based ".pyc" files, Python simply
assumes the cache file is valid if it exists. Hash-based ".pyc" files
validation behavior may be overridden with the "--check-hash-based-
pycs" flag.

バージョン 3.7 で変更: Added hash-based ".pyc" files. Previously,
Python only supported timestamp-based invalidation of bytecode caches.


5.5. パスベース・ファインダー
=============================

上で触れた通り、 Python にはいくつかのデフォルトのメタパス・ファインダ
ーが備わっています。そのうちの 1 つは *パスベース・ファインダー*
("PathFinder") と呼ばれ、 *パスエントリ* のリストである *インポートパ
ス* を検索します。それぞれのパスエントリは、モジュールを探す場所を指し
ています。

パスベース・ファインダー自体は何かのインポート方法を知っているわけでは
ありません。その代わりに、個々のパスエントリを走査し、それぞれに特定の
種類のパスの扱いを知っているパスエントリ・ファインダーを関連付けます。

デフォルトのパスエントリ・ファインダーは、ファイルシステム上のモジュー
ルを見つけるためのすべてのセマンティクスを実装しています。それは
Python ソースコード (".py" ファイル) 、Python バイトコード (".pyc" フ
ァイル) 、共有ライブラリ (例えば ".so" ファイル) などの特別なファイル
タイプを処理します。標準ライブラリの "zipimport" モジュールによってサ
ポートされる場合は、デフォルトのパスエントリ・ファインダーは (共有ライ
ブラリ以外の) すべてのファイルタイプの zip ファイルからのロードも扱い
ます。

パスエントリはファイルシステム上の場所に限定される必要はありません。
URL やデータベースクエリやその他文字列で指定できる場所を参照することも
可能です。

パスベース・ファインダーにはフックやプロトコルを追加することができ、そ
れによって検索可能なパスエントリの種類を拡張し、カスタマイズすることが
できます。例えば、ネットワーク上の URL をパスエントリとしてサポートし
たい場合、 web 上のモジュールを見つけるために HTTP の取り扱い方を実装
したフックを書くことができます。この (呼び出し可能オブジェクトである)
フックは、下で解説するプロトコルをサポートする *パスエントリ・ファイン
ダー* を返します。このプロトコルは  web からモジュールのローダーを取得
するのに使われます。

警告の言葉: この節と前の節の両方で *ファインダー* という言葉が、 *メタ
パス・ファインダー* と *パスエントリ・ファインダー* という用語で区別さ
れて使われています。これら 2 種類のファインダーは非常に似ており、似た
プロトコルをサポートし、インポート処理で同じように機能しますが、微妙に
異なっているのを心に留めておくのは重要です。特に、メタパス・ファインダ
ーはインポート処理の開始時、 "sys.meta_path" の走査が動くときに動作し
ます。

それとは対照的に、パスエントリ・ファインダーはある意味でパスベース・フ
ァインダーの実装詳細であり、実際 "sys.meta_path" からパスベース・ファ
インダーが取り除かれた場合、パスエントリ・ファインダーの実装は何も実行
されないでしょう。


5.5.1. パスエントリ・ファインダー
---------------------------------

*パスベース・ファインダー* には、文字列 *パスエントリ* で指定された場
所の Python モジュールや Python パッケージを見つけ、ロードする責任があ
ります。ほとんどのパスエントリはファイルシステム上の場所を指定していま
すが、そこに制限される必要はありません。

メタパス・ファインダーとして、 *パスベース・ファインダー* には前に解説
した "find_spec()" プロトコルが実装されていますが、これに加えて *イン
ポートパス* からモジュールを見つけ、ロードする方法をカスタマイズするた
めに使えるフックを提供しています。

*パスベース・ファインダー* は "sys.path" 、 "sys.path_hooks" 、
"sys.path_importer_cache" という 3 つの変数を使います。さらにパッケー
ジオブジェクトの "__path__" 属性も使います。これらによって、インポート
処理をカスタマイズする方法が提供されます。

"sys.path" には、モジュールとパッケージを探す場所文字列の一覧がありま
す。これは "PYTHONPATH" 環境変数とその他様々なインストール方法や実装に
依存するデフォルト値で初期化されます。 "sys.path" 内の要素は、ファイル
システム上のディレクトリや zip ファイルやその他モジュールを探すべき "
場所" となりうるもの ("site" モジュールを参照) を指すことができます。
文字列およびバイト列のみを "sys.path" に入れるべきです; 他のデータ型は
無視されます。バイト列の要素のエンコーディングは、各 *パスエントリ・フ
ァインダー* によって判別されます。

*パスベース・ファインダー* は *メタパス・ファインダー* なので、インポ
ート機構は、前で解説したパスベース・ファインダーの "find_spec()"  メソ
ッドを呼び出すことで *インポートパス* の検索を始めます。 "path" 引数が
"find_spec()" に渡されたときは、それは走査するパス文字列のリスト - 典
型的にはそのパッケージの中でインポートしているパッケージの "__path__"
属性になります。 "path" 引数が "None" だった場合、それは最上位のインポ
ートであることを示していて、 "sys.path" が使われます。

パスベース・ファインダーは検索パスのすべての要素について反復処理をし、
それぞれのパスに対して適切な *パスエントリ・ファインダー*
("PathEntryFinder") を探します。これは時間のかかる処理 (例えば、この検
索のための "stat()" 呼び出しのオーバーヘッド) になり得るので、パスベー
ス・ファインダーはパス要素からパスエントリ・ファインダーへの対応付けを
キャッシュとして持っておきます。このキャッシュは
"sys.path_importer_cache" に持っています (名前に反して、このキャッシュ
は実際には *インポーター* には制限されておらず、ファインダーオブジェク
トを保持します) 。このようにして、時間のかかる特定の *パスエントリ* の
場所のための *パスエントリ・ファインダー* の検索を一度だけ検索すれば良
くなります。パスベース・ファインダーにパスエントリの検索を再度行わせる
ために、ユーザコードでは自由に "sys.path_importer_cache" からキャッシ
ュを取り除いて構いません  [3] 。

path entry がキャッシュの中に無かった場合、 path based finder は
"sys.path_hooks" の中の呼び出し可能オブジェクトを全て辿ります。 このリ
ストのそれぞれの *path entry フック* は、検索する path entry という引
数 1 つを渡して呼び出されます。 その呼び出し可能オブジェクトは path
entry を扱える *path entry finder* を返すか、  "ImportError" を送出し
ます。 "ImportError" は、フックが *path entry* のための *path entry
finder* を探せないことを報せるために path based finder が使います。 こ
の例外は処理されず、 *import path* を辿っていく処理が続けられます。 フ
ックは引数として文字列またはバイト列オブジェクトを期待します; バイト列
オブジェクトのエンコーディングはフックに任されていて (例えば、ファイル
システムのエンコーディングの UTF-8 やそれ以外などです) 、フックが引数
をデコードできなかった場合は "ImportError" を送出すべきです。

"sys.path_hooks" を辿る処理が *パスエントリ・ファインダー* を何も返さ
ずに終わった場合、パスベース・ファインダーの "find_spec()" メソッドは
、 "sys.path_importer_cache" に (このパスエントリに対するファインダー
が存在しないことを示すために) "None" を保存し、 *メタパス・ファインダ
ー* はモジュールが見つからなかったことを伝えるために "None" を返します
。

"sys.path_hooks" 上の *パスエントリフック* 呼び出し可能オブジェクトの
戻り値のいずれかが *パスエントリ・ファインダー* *であった* 場合、後で
出てくるモジュール仕様を探すためのプロトコルが使われ、それがモジュール
をロードするために使われます。

（空の文字列によって表される）現在のディレクトリは、 "sys.path" の他の
エントリとは多少異なる方法で処理されます。まず、現在のディレクトリが存
在しないことが判明した場合、 "sys.path_importer_cache" には何も追加さ
れません。次に、現在のディレクトリに対する値は個々のモジュールのルック
アップで毎回新たに検索されます。 3番目に、 "sys.path_importer_cache"
に使われ、 "importlib.machinery.PathFinder.find_spec()" が返すパスは、
実際のディレクトリであって空の文字列ではありません。


5.5.2. パスエントリ・ファインダー・プロトコル
---------------------------------------------

モジュールと初期化されたパッケージのインポートをサポートするため、およ
び名前空間パッケージのポーションとして提供するために、パスエントリ・フ
ァインダーは "find_spec()"  メソッドを実装しなければいけません。

"find_spec()" は 2 つの引数を取ります。インポートしようとしているモジ
ュールの完全修飾名と、 (オプションの) 対象モジュールです。
*find_spec()* はモジュールに対応する完全に初期化 (populated) された仕
様を返します。この仕様は (1つの例外を除いて) 常に "loader" セットを持
っています。

モジュール仕様が名前空間 *ポーション* を表していることをインポート機構
に示すために、パスエントリ・ファインダーはモジュール仕様の
"submodule_search_locations" を名前空間ポーションを含むリストに設定し
ます。

バージョン 3.4 で変更: "find_spec()" は "find_loader()" と
"find_module()" を置き換えました。両者は deprecated ですが、
*find_spec()* が定義されていなければ使われます。古いパスエントリ・ファ
インダーの中には、 "find_spec()" の代わりにこれら 2 つの deperecated
なメソッドのうちのいずれかを実装しているものがあるかもしれません。これ
らのメソッドは後方互換性のためにまだ考慮されています。しかし、パスエン
トリ・ファインダーに "find_spec()" が実装されていれば、古いメソッドは
無視されます。"find_loader()" takes one argument, the fully qualified
name of the module being imported.  "find_loader()" returns a 2-tuple
where the first item is the loader and the second item is a namespace
*portion*.他のインポート機構の実装に対する後方互換性のために、多くのパ
スエントリ・ファインダーは、メタパス・ファインダーがサポートするのと同
じ伝統的な "find_module()"  メソッドもサポートしています。しかし、パス
エントリ・ファインダーの "find_module()"  メソッドは、決して "path" 引
数では呼び出されません (このメソッドは、パスフックの最初の呼び出しから
適切なパス情報を記録する動作が期待されています)。パスエントリ・ファイ
ンダーの "find_module()" メソッドは deprecated です。なぜなら、その方
法ではパスエントリ・ファインダーが名前空間パッケージに対してポーション
を提供することができないからです。もし "find_loader()" と
"find_module()" の両方がパスエントリ・ファインダーに存在したら、インポ
ートシステムは常に "find_module()" よりも "find_loader()" を優先して呼
び出します。

バージョン 3.10 で変更: Calls to "find_module()" and "find_loader()"
by the import system will raise "ImportWarning".


5.6. 標準のインポートシステムを置き換える
=========================================

インポートシステム全体を置き換えるための最も信頼性のある仕組みは、
"sys.meta_path" のデフォルトの内容を削除し、全部をカスタムのメタパスフ
ックで置き換えるものです。

もし、 import 文の動作だけを変更し、インポートシステムにアクセスする他
の API には影響を与えなくてもよければ、組み込みの "__import__()" 関数
を置き換えるだけで十分です。この手法は、ある 1 つのモジュール内だけで
import 文の動作を変更するのにも用いられます。

(標準のインポートシステム全体を停止するのではなく) すでにメタパスにい
るフックからあるモジュールのインポートを選択的に防ぐためには、
"find_spec()" から "None" を返す代わりに、直接 "ModuleNotFoundError"
を送出するだけで十分です。 "None" を返すのはメタパスの走査を続けるべき
であることを意味しますが、例外を送出するとすぐに走査を打ち切ります。


5.7. Package Relative Imports
=============================

Relative imports use leading dots. A single leading dot indicates a
relative import, starting with the current package. Two or more
leading dots indicate a relative import to the parent(s) of the
current package, one level per dot after the first. For example, given
the following package layout:

   package/
       __init__.py
       subpackage1/
           __init__.py
           moduleX.py
           moduleY.py
       subpackage2/
           __init__.py
           moduleZ.py
       moduleA.py

In either "subpackage1/moduleX.py" or "subpackage1/__init__.py", the
following are valid relative imports:

   from .moduleY import spam
   from .moduleY import spam as ham
   from . import moduleY
   from ..subpackage1 import moduleY
   from ..subpackage2.moduleZ import eggs
   from ..moduleA import foo

Absolute imports may use either the "import <>" or "from <> import <>"
syntax, but relative imports may only use the second form; the reason
for this is that:

   import XXX.YYY.ZZZ

should expose "XXX.YYY.ZZZ" as a usable expression, but .moduleY is
not a valid expression.


5.8. __main__ に対する特別な考慮
================================

"__main__" モジュールは、 Python のインポートシステムに関連する特別な
ケースです。 他の場所 で言及されているように、 "__main__" モジュールは
"sys" や "builtins" などと同様にインタプリタースタートアップで直接初期
化されます。しかし、前者 2 つのモジュールと違って、 "__main__" は厳密
にはビルトインのモジュールとしての資格を持っていません。これは、
"__main__" が初期化される方法がインタプリタが起動されるときのフラグや
その他のオプションに依存するためです。


5.8.1. __main__.__spec__
------------------------

"__main__" がどのように初期化されるかに依存して、 "__main__.__spec__"
は適切に設定されることもあれば "None" になることもあります。

Python が "-m" オプションを付けて実行された場合には、 "__spec__" は対
応するモジュールまたはパッケージのモジュール仕様に設定されます。また、
ディレクトリや zip ファイル、または他の "sys.path" エントリを実行する
処理の一部として "__main__" モジュールがロードされる場合にも
"__spec__" が生成 (populate) されます。

それ以外のケース では、 "__main__.__spec__" は "None" に設定されます。
これは、 "__main__" を生成 (populate) するために使われたコードがインポ
ート可能なモジュールと直接一致していないためです:

* 対話プロンプト

* "-c" オプション

* stdin から起動された場合

* ソースファイルやバイトコードファイルから直接起動された場合

最後のケースでは、たとえ技術的にはファイルがモジュールとして直接インポ
ートできた *としても* "__main__.__spec__" は常に "None" になることに注
意してください。もし "__main__" において有効なモジュールメタデータが必
要なら "-m" スイッチを使ってください。

"__main__" がインポート可能なモジュールと一致し、 "__main__.__spec__"
がそれに応じて設定されていたとしても、それでもなお、この 2 つのモジュ
ールは別物とみなされることに注意してください。これは、 "if __name__ ==
"__main__":" チェックによって保証されるブロックは、 "__main__" 名前空
間を生成 (populate) するためにモジュールが使用される時にだけ実行され、
通常のインポート時には実行されない、という事実に起因しています。


5.9. 参考資料
=============

Python の初期の頃からすると、インポート機構は目覚ましい発展を遂げまし
た。 一部細かいところがドキュメントが書かれたときから変わってはいます
が、最初期の パッケージの仕様 はまだ読むことができます。

オリジナルの "sys.meta_path" の仕様は **PEP 302** で、その後継となる拡
張が **PEP 420** です。

**PEP 420** は Python 3.3 に *名前空間パッケージ* を導入しています。
**PEP 420** はまた "find_module()" に代わるものとして "find_loader()"
プロトコルを導入しています。

**PEP 366** は、メインモジュールでの明示的な相対インポートのために追加
した "__package__" 属性の解説をしています。

**PEP 328** は絶対インポート、明示的な相対インポート、および、当初
"__name__" で提案し、後に **PEP 366** が "__package__" で定めた仕様を
導入しました。

**PEP 338** はモジュールをスクリプトとして実行するときの仕様を定めてい
ます。

**PEP 451** は、モジュール仕様オブジェクトにおけるモジュール毎のインポ
ート状態のカプセル化を追加しています。また、ローダーの定型的な責任のほ
とんどをインポート機構に肩代わりさせています。これらの変更により、イン
ポートシステムのいくつかの API が deprecate され、またファインダーとロ
ーダーには新しいメソッドが追加されました。

-[ 脚注 ]-

[1] "types.ModuleType" を参照してください。

[2] importlib の実装は、戻り値を直接使うことは避けています。その代わり
    に、モジュール名を調べて "sys.modules" からモジュールオブジェクト
    を得ます。こうすることの間接的な効果は、インポートされたモジュール
    が "sys.modules" にいる自分自身を置き換えることがあるということで
    す。これは実装依存の動作であり、他の Python 実装では保証されていな
    い動作です。

[3] レガシーなコードでは、 "sys.path_importer_cache" に
    "imp.NullImporter" のインスタンスがいることがあります。それの代わ
    りに "None" を使うようにコードを変更することが推奨されます。より詳
    しいことは Python コードの移植 を参照してください。
