"importlib" --- "import" の実装
*******************************

Added in version 3.1.

**ソースコード:** Lib/importlib/__init__.py

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


はじめに
========

"importlib" パッケージには 3 つの目的があります。

1 つ目は "import" 文 (ひいては "__import__()" 関数) の実装を Python の
ソースコードで提供することです。 これにより、どの Python インタープリ
ターにも移植できる "import" の実装を提供します。 また、Python 以外のプ
ログラミング言語による実装よりも理解しやすい実装になります。

2つ目の目的は、このパッケージが公開している "import" を実装するための
要素を利用して、(*インポーター* として知られる) インポートプロセスで動
作するカスタムのオブジェクトを実装しやすくすることです。

3 つ目は、Python パッケージのさまざまな側面を管理する追加機能を提供す
るモジュールを含むことです。

* "importlib.metadata" はサードパーティの配布物のメタデータへのアクセ
  スを提供します。

* "importlib.resources" は Python パッケージ内のコード以外の「リソース
  」にアクセスする機能を提供します。

参考:

  import 文
     "import" 文の言語リファレンス。

  Packages specification
     パッケージの元の仕様。幾つかの動作はこの仕様が書かれた頃から変更
     されています (例: "sys.modules" で "None" に基づくリダイレクト)。

  "__import__()" 関数
     "import" 文はこの関数のシンタックスシュガーです。

  sys.path モジュール検索パスの初期化
     "sys.path" の初期化について説明します。

  **PEP 235**
     大文字小文字を区別しないプラットフォームでのインポート

  **PEP 263**
     Python のソースコードのエンコーディング

  **PEP 302**
     新しいインポートフック

  **PEP 328**
     複数行のインポートと、絶対/相対インポート

  **PEP 366**
     main モジュールの明示的な相対インポート

  **PEP 420**
     暗黙的な名前空間パッケージ

  **PEP 451**
     インポートシステムのための ModuleSpec 型

  **PEP 488**
     PYO ファイルの撤廃

  **PEP 489**
     複数フェーズでの拡張モジュールの初期化

  **PEP 552**
     決定論的 pyc

  **PEP 3120**
     デフォルトのソースエンコーディングとして UTF-8 を使用

  **PEP 3147**
     PYC リポジトリディレクトリ


関数
====

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)

   組み込みの "__import__()" 関数の実装です。

   注釈:

     プログラムからモジュールをインポートする場合はこの関数の代わりに
     "import_module()" を使ってください。

importlib.import_module(name, package=None)

   モジュールをインポートします。*name* 引数は、インポートするモジュー
   ルを絶対または相対表現 (例えば "pkg.mod" または "..mod") で指定しま
   す。name が相対表現で与えられたら、*package* 引数を、パッケージ名を
   解決するためのアンカーとなるパッケージの名前に設定する必要がありま
   す (例えば "import_module('..mod', 'pkg.subpkg')" は "pkg.mod" をイ
   ンポートします)。

   "import_module()" 関数は "importlib.__import__()" を単純化するラッ
   パーとして働きます。つまり、この関数のすべての意味は
   "importlib.__import__()" から受け継いでいます。これらの2つの関数の
   最も重要な違いは、 "import_module()" が指定されたパッケージやモジュ
   ール (例えば "pkg.mod") を返すのに対し、 "__import__()" はトップレ
   ベルのパッケージやモジュール (例えば "pkg") を返すことです。

   もしモジュールを動的にインポートしていて、インタープリタの実行開始
   後にモジュールが作成された (例えば、 Python ソースファイルを作成し
   た) 場合、インポートシステムが新しいモジュールを見つけられるように
   、 "invalidate_caches()" を呼ぶ必要があるでしょう。

   モジュールをインポートできない場合、"import_module()" は
   "ImportError" または "ModuleNotFoundError" などの適切なサブクラスを
   送出します。

   バージョン 3.3 で変更: 親パッケージは自動的にインポートされます。

importlib.invalidate_caches()

   "sys.meta_path" に保存されたファインダーの内部キャッシュを無効にし
   ます。 ファインダーが "invalidate_caches()" を実装していれば、無効
   化のために呼び出します。 プログラムの実行中にモジュールを作成または
   インストールした場合は、すべてのファインダーが新しいモジュールの存
   在を認識できるよう、この関数を呼び出してください。

   Added in version 3.3.

   バージョン 3.10 で変更: 同じ名前空間をすでにインポートした後に、
   "sys.path" の別の場所に作成またはインストールされた名前空間パッケー
   ジも認識するようになりました。

importlib.reload(module)

   以前にインポートされた *module* をリロードします。引数はモジュール
   オブジェクトでなければならず、したがってそれ以前に必ずインポートに
   成功していなければなりません。この関数は、モジュールのソースファイ
   ルを外部エディタで編集していて Python インタープリタから離れること
   なく新しいバージョンを試したい際に便利です。戻り値はモジュールオブ
   ジェクトです。 (もし再インポートが異なるオブジェクトを
   "sys.modules" に配置したら、元の *module* とは異なるかもしれません
   。)

   "reload()" が実行された場合:

   * Python モジュールのコードは再コンパイルされ、モジュールレベルのコ
     ードが再度実行されます。モジュールの辞書中にある何らかの名前に結
     び付けられたオブジェクトは、そのモジュールを最初にロードしたとき
     の *ローダー* を再利用して新たに定義されます。拡張モジュールの
     "init" 関数が二度呼び出されることはありません。

   * Python における他のオブジェクトと同様、以前のオブジェクトのメモリ
     領域は、参照カウントがゼロにならないかぎり再利用されません。

   * モジュール名前空間内の名前は新しいオブジェクト (または更新された
     オブジェクト) を指すよう更新されます。

   * 以前のオブジェクトが (外部の他のモジュールなどからの) 参照を受け
     ている場合、それらを新たなオブジェクトに再束縛し直すことはないの
     で、必要なら自分で名前空間を更新しなければなりません。

   いくつか補足説明があります:

   モジュールが再ロードされた際、その辞書 (モジュールのグローバル変数
   を含みます) はそのまま残ります。名前の再定義を行うと、以前の定義を
   上書きするので、一般的には問題はありません。新たなバージョンのモジ
   ュールが古いバージョンで定義された名前を定義していない場合、古い定
   義がそのまま残ります。辞書がグローバルテーブルやオブジェクトのキャ
   ッシュを維持していれば、この機能をモジュールを有効性を引き出すため
   に使うことができます --- つまり、 "try" 文を使えば、必要に応じてテ
   ーブルがあるかどうかをテストし、その初期化を飛ばすことができます:

      try:
          cache
      except NameError:
          cache = {}

   組み込みモジュールや動的にロードされるモジュールを再ロードすること
   は、一般的にそれほど便利ではありません。 "sys", "__main__",
   "builtins" やその他重要なモジュールの再ロードはお勧め出来ません。
   多くの場合、拡張モジュールは 複数回初期化されるようには設計されてお
   らず、再ロードされた場合には何らかの理由で失敗するかもしれません。

   一方のモジュールが "from" ... "import" ... を使って、オブジェクトを
   他方のモジュールからインポートしているなら、他方のモジュールを
   "reload()" で呼び出しても、そのモジュールからインポートされたオブジ
   ェクトを再定義することはできません --- この問題を回避する一つの方法
   は、 "from" 文を再度実行することで、もう一つの方法は "from" 文の代
   わりに "import" と限定的な名前 (*module.name*) を使うことです。

   あるモジュールがクラスのインスタンスを生成している場合、そのクラス
   を定義しているモジュールの再ロードはそれらインスタンスのメソッド定
   義に影響しません --- それらは古いクラス定義を使い続けます。これは派
   生クラスの場合でも同じです。

   Added in version 3.4.

   バージョン 3.7 で変更: リロードされたモジュールの "ModuleSpec" が欠
   けていたときは "ModuleNotFoundError" が送出されます。

   警告:

     この関数はスレッドセーフではありません。 複数のスレッドから呼び出
     すと、予期しない動作を引き起こすことがあります。 スレッドセーフに
     モジュールをリロードするには、"threading.Lock" や他の同期プリミテ
     ィブの使用を推奨します。


"importlib.abc" -- インポートに関連する抽象基底クラス
=====================================================

**ソースコード:** Lib/importlib/abc.py

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

"importlib.abc" モジュールは、"import" が使う主要な抽象基底クラスをす
べて含みます。 これらの ABC の実装を支援するため、主要な抽象基底クラス
のサブクラスもいくつか提供します。

抽象基底クラス階層:

   object
    +-- MetaPathFinder
    +-- PathEntryFinder
    +-- Loader
         +-- ResourceLoader --------+
         +-- InspectLoader          |
              +-- ExecutionLoader --+
                                    +-- FileLoader
                                    +-- SourceLoader

class importlib.abc.MetaPathFinder

   *meta path finder* を表す抽象基底クラスです。

   Added in version 3.3.

   バージョン 3.10 で変更: "Finder" のサブクラスではなくなりました。

   find_spec(fullname, path, target=None)

      指定されたモジュールの *スペック* を検索する抽象メソッドです。
      トップレベルのインポートの場合、*path* は "None" です。 それ以外
      の場合はサブパッケージやモジュールの検索で、*path* は親パッケー
      ジの "__path__" の値です。 スペックが見つからなければ "None" を
      返します。 "target" が渡される場合はモジュールオブジェクトであり
      、ファインダーが返すスペックをより的確に判断するために使えます。
      具体的な "MetaPathFinders" の実装には、
      "importlib.util.spec_from_loader()" が役立つ場合があります。

      Added in version 3.4.

   invalidate_caches()

      このファインダーで使われている内部キャッシュがあれば無効にするオ
      プションのメソッドです。 "sys.meta_path" 上のすべてのファインダ
      ーのキャッシュを無効化する際、 "importlib.invalidate_caches()"
      によって使われます。

      バージョン 3.4 で変更: 呼び出された際に "NotImplemented" ではな
      く "None" を返すようになりました。

   discover(parent=None)

      指定された *parent* モジュールのスペックを使い、見つかる可能性の
      あるスペックを検索するオプションのメソッドです。 *parent* が
      *None* の場合、"MetaPathFinder.discover()" はトップレベルのモジ
      ュールを検索します。

      見つかる可能性のあるスペックのイテラブルを返します。

      *parent* がパッケージモジュールでなければ "ValueError" を送出し
      ます。

      警告:

        このメソッドは非常に多くのオブジェクトを yield する可能性があ
        り、これらの値を計算する際に入出力操作を行うこともあります。そ
        のため、通常は結果の値を必要になったときにその都度計算するのが
        望ましいでしょう。 したがって、戻り値として保証されるのは "イ
        テラブル" であることだけであり、"list" や他の "コレクション"
        型とは限りません。

      Added in version 3.15.

class importlib.abc.PathEntryFinder

   *path entry finder* を表す抽象基底クラスです。 "MetaPathFinder" と
   似ているところがありますが、 "PathEntryFinder" は
   "importlib.machinery.PathFinder" が提供するパスに基づく import サブ
   システムの中でのみ使うことが意図されています。

   Added in version 3.3.

   バージョン 3.10 で変更: "Finder" のサブクラスではなくなりました。

   find_spec(fullname, target=None)

      指定されたモジュールに対応する *スペック* を検索する抽象メソッド
      。ファインダーは、割り当てられている *パス・エントリー* 内のモジ
      ュールだけを検索します。スペックが見つからなければ "None" が返さ
      れます。 "target" は、渡されてきたならモジュールオブジェクトです
      。これはファインダーがどのようなスペックを返せばよいか推測するた
      めに使用します。具体的な "PathEntryFinders" を実装するためには
      "importlib.util.spec_from_loader()" が便利かもしれません。

      Added in version 3.4.

   invalidate_caches()

      このファインダーで使われている内部キャッシュがあれば無効にするオ
      プションのメソッドです。キャッシュされたすべてのファインダーの無
      効化する際、
      "importlib.machinery.PathFinder.invalidate_caches()" によって使
      われます。

   discover(parent=None)

      指定された *parent* モジュールのスペックを使い、見つかる可能性の
      あるスペックを検索するオプションのメソッドです。 *parent* が
      *None* の場合、"PathEntryFinder.discover()" はトップレベルのモジ
      ュールを検索します。

      見つかる可能性のあるスペックのイテラブルを返します。

      *parent* がパッケージモジュールでなければ "ValueError" を送出し
      ます。

      警告:

        このメソッドは非常に多くのオブジェクトを yield する可能性があ
        り、これらの値を計算する際に入出力操作を行うこともあります。そ
        のため、通常は結果の値を必要になったときにその都度計算するのが
        望ましいでしょう。 したがって、戻り値として保証されるのは "イ
        テラブル" であることだけであり、"list" や他の "コレクション"
        型とは限りません。

      Added in version 3.15.

class importlib.abc.Loader

      *loader* の抽象基底クラスです。ローダーの厳密な定義は **PEP
      302** を参照してください。

      リソースの読み取りをサポートするローダーは、
      "importlib.resources.abc.ResourceReader" で定められた
      "get_resource_reader()" メソッドを実装する必要があります。

      バージョン 3.7 で変更: オプションの "get_resource_reader()" メソ
      ッドを導入しました。

   バージョン 3.15 で変更: "load_module()" メソッドを削除しました。

   create_module(spec)

      モジュールをインポートする際に使用されるモジュールオブジェクトを
      返すメソッド。このメソッドは "None" を戻すことができ、その場合は
      デフォルトのモジュール作成のセマンティクスが適用されることを示し
      ます。

      Added in version 3.4.

      バージョン 3.6 で変更: "exec_module()" が定義されている場合は、
      このメソッドはオプションではなくなりました。

   exec_module(module)

      モジュールがインポートまたはリロードされる際に、そのモジュールを
      モジュール自身の名前空間の中で実行する抽象的なメソッド。
      "exec_module()" が呼ばれる時点で、モジュールはすでに初期設定され
      ている必要があります。 このメソッドが存在するときは、
      "create_module()" の定義が必須です。

      Added in version 3.4.

      バージョン 3.6 で変更: "create_module()" の定義が必須となりまし
      た。

class importlib.abc.ResourceLoader

   *TraversableResources に取って代わられました*

      *loader* の抽象基底クラスで、ストレージバックエンドから任意のリ
      ソースをロードするオプションの **PEP 302** プロトコルを実装しま
      す。

      バージョン 3.7 で非推奨: この ABC は非推奨です。 代わりに
      "importlib.resources.abc.TraversableResources" を通じてリソース
      をロードしてください。 このクラスは、このモジュールの他の ABC と
      の後方互換性のためだけに存在します。

      abstractmethod get_data(path)

            *path* にあるデータをバイト列として返す抽象メソッドです。
            任意のデータを保存できる、ファイルに似たストレージバックエ
            ンドを持つローダーは、この抽象メソッドを実装し、保存された
            データへの直接アクセスを提供できます。 *path* が見つからな
            ければ "OSError" を送出する必要があります。 *path* は、モ
            ジュールの "__file__" 属性か、パッケージの "__path__" の要
            素を使って構築することを想定しています。

            バージョン 3.4 で変更: "NotImplementedError" の代わりに
            "OSError" を送出します。

class importlib.abc.InspectLoader

   *loader* の抽象基底クラスで、ローダーがモジュールを検査するためのオ
   プションの **PEP 302** プロトコルを実装します。

   get_code(fullname)

      モジュールの "code" オブジェクトを返すか、 (例えば組み込みモジュ
      ールの場合に) モジュールがコードオブジェクトを持たなければ
      "None" を返します。要求されたモジュールをローダーが見つけられな
      かった場合は "ImportError" を送出します。

      注釈:

        このメソッドにはデフォルト実装がありますが、とはいえパフォーマ
        ンスのために、可能ならばオーバライドしたほうが良いです。

      バージョン 3.4 で変更: このメソッドはもはや抽象メソッドではなく
      、具象実装が提供されます。

   abstractmethod get_source(fullname)

         モジュールのソースを返す抽象メソッドです。これは認識されたす
         べての行セパレータを "'\n'" 文字に変換し、 *universal
         newlines* を使ったテキスト文字列として返されます。利用できる
         ソースがなければ (例えば組み込みモジュール)、 "None" を返しま
         す。指定されたモジュールが見つからなければ、 "ImportError" を
         送出します。

         バージョン 3.4 で変更: "NotImplementedError" の代わりに
         "ImportError" を送出します。

   is_package(fullname)

      モジュールがパッケージであれば True を返し、そうでなければ False
      を返すオプションのメソッドです。 *ローダー* がモジュールを見つけ
      られなかったなら "ImportError" が送出されます。

      バージョン 3.4 で変更: "NotImplementedError" の代わりに
      "ImportError" を送出します。

   static source_to_code(data, path='<string>', fullname=None)

      Python のソースからコードオブジェクトを作ります。

      *data* 引数は "compile()" 関数がサポートするもの (すなわち文字列
      かバイト) なら何でも構いません。*path* 引数はソースコードの元々
      の場所への "パス" でなければなりませんが、抽象概念 (例えば zip
      ファイル内の場所) でも構いません。

      結果のコードオブジェクトを使って、 "exec(code, module.__dict__)"
      を呼ぶことでモジュール内でコードを実行できます。

      オプションの *fullname* 引数はモジュール名を指定します。 構文の
      警告をモジュール名で曖昧さなく フィルタリング するために必要です
      。

      Added in version 3.4.

      バージョン 3.5 で変更: スタティックメソッドになりました。

      Added in version 3.15: *fullname* 引数を追加しました。

   exec_module(module)

      "Loader.exec_module()" の実装です。

      Added in version 3.4.

class importlib.abc.ExecutionLoader

   "InspectLoader" から継承された抽象基底クラスで、実装されていれば、
   モジュールをスクリプトとして実行する助けになります。この抽象基底ク
   ラスはオプションの **PEP 302** プロトコルを表します。

   abstractmethod get_filename(fullname)

         指定されたモジュールの "__file__" の値を返す抽象メソッドです
         。 パスが利用できなければ "ImportError" を送出します。

         ソースコードが利用できるなら、そのモジュールのロードにバイト
         コードが使われたかにかかわらず、このメソッドはそのソースファ
         イルへのパスを返す必要があります。

         バージョン 3.4 で変更: "NotImplementedError" の代わりに
         "ImportError" を送出します。

class importlib.abc.FileLoader(fullname, path)

   "ResourceLoader" と "ExecutionLoader" から継承された抽象基底クラス
   で、 "ResourceLoader.get_data()" および
   "ExecutionLoader.get_filename()" の具象実装を提供します。

   *fullname* 引数は、ローダーが解決しようとするモジュールの、完全に解
   決された名前です。*path* 引数は、モジュールのファイルへのパスです。

   Added in version 3.3.

   バージョン 3.15 で変更: "load_module()" メソッドを削除しました。

   name

      ローダーが扱えるモジュールの名前です。

   path

      モジュールのファイルへのパスです。

   abstractmethod get_filename(fullname)

      "path" を返します。

   abstractmethod get_data(path)

      *path* をバイナリファイルとして読み込み、そのバイト列を返します
      。

class importlib.abc.SourceLoader

   ソース (オプションでバイトコード) ファイルのロードを実装する抽象基
   底クラスです。このクラスは、 "ResourceLoader" と "ExecutionLoader"
   の両方を継承し、以下の実装が必要です:

   * "ResourceLoader.get_data()"

   * "ExecutionLoader.get_filename()"
        ソースファイルへのパスのみを返す必要があります。ソースなしのロ
        ードはサポートされていません。

   このクラスでこれらの抽象メソッドを定義することで、バイトコードファ
   イルを追加でサポートします。 これらのメソッドを定義しなければ (また
   はそのメソッドが "NotImplementedError" を送出すれば)、このローダー
   はソースコードに対してのみ働きます。 これらのメソッドを実装すること
   で、ローダーはソースとバイトコードファイル *の組み合わせ* に対して
   働きます。 バイトコードのみを与えた *ソースのない* ロードは認められ
   ません。 バイトコードファイルは、 Python コンパイラによる解析の工程
   をなくして速度を上げる最適化です。 ですから、バイトコード特有の API
   は公開されていません。

   バージョン 3.15 で変更: "load_module()" メソッドを削除しました。

   path_stats(path)

      指定されたパスについてのメタデータを含む "dict" を返す、オプショ
      ンの抽象メソッドです。サポートされる辞書のキーは:

      * "'mtime'" (必須): ソースコードの更新時刻を表す整数または浮動小
        数点数です。

      * "'size'" (任意): バイト数で表したソースコードのサイズです。

      未来の拡張のため、辞書内の他のキーは無視されます。パスが扱えなけ
      れば、 "OSError" が送出されます。

      Added in version 3.3.

      バージョン 3.4 で変更: "NotImplementedError" の代わりに
      "OSError" を送出します。

   path_mtime(path)

      指定されたパスの更新時刻を返す、オプションの抽象メソッドです。

      バージョン 3.3 で非推奨: このメソッドは非推奨で、代わりに
      "path_stats()" を使います。 実装する必要はありませんが、互換性の
      ために引き続き利用できます。 パスを扱えない場合は "OSError" を送
      出してください。

      バージョン 3.4 で変更: "NotImplementedError" の代わりに
      "OSError" を送出します。

   set_data(path, data)

      ファイルパスに指定されたバイト列を書き込むオプションの抽象メソッ
      ドです。存在しない中間ディレクトリがあれば、自動で作成されます。

      パスが読み取り専用のために書き込みが失敗した場合
      ("errno.EACCES"/"PermissionError")、例外を伝播させないでください
      。

      バージョン 3.4 で変更: 呼ばれたときに "NotImplementedError" を送
      出することは最早ありません。

   get_code(fullname)

      "InspectLoader.get_code()" の具象実装です。

   exec_module(module)

      "Loader.exec_module()" の具象実装です。

      Added in version 3.4.

   get_source(fullname)

      "InspectLoader.get_source()" の具象実装です。

   is_package(fullname)

      "InspectLoader.is_package()" の具象実装です。モジュールは、次の
      *両方* を満たすならパッケージであると決定されます。モジュールの
      ("ExecutionLoader.get_filename()" で与えられる) ファイルパスが、
      ファイル拡張子を除くと "__init__" という名のファイルであること。
      モジュール名自体が "__init__" で終わらないこと。


"importlib.machinery" -- インポーターとパスフック
=================================================

**ソースコード:** Lib/importlib/machinery.py

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

このモジュールには、 "import" がモジュールを検索してロードするのに役立
つ様々なオブジェクトがあります。

importlib.machinery.SOURCE_SUFFIXES

   認識されているソースモジュールのファイル接尾辞を表す文字列のリスト
   です。

   Added in version 3.3.

importlib.machinery.DEBUG_BYTECODE_SUFFIXES

   最適化されていないバイトコードモジュールのファイル接尾辞を表す文字
   列のリストです。

   Added in version 3.3.

   バージョン 3.5 で非推奨: 代わりに "BYTECODE_SUFFIXES" を使ってくだ
   さい。

importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES

   最適化されたバイトコードモジュールのファイル接尾辞を表す文字列のリ
   ストです。

   Added in version 3.3.

   バージョン 3.5 で非推奨: 代わりに "BYTECODE_SUFFIXES" を使ってくだ
   さい。

importlib.machinery.BYTECODE_SUFFIXES

   認識されているバイトコードモジュールのファイル接尾辞を表す文字列の
   リストです (先頭のドットを含みます)。

   Added in version 3.3.

   バージョン 3.5 で変更: この値は "__debug__" に依存しなくなりました
   。

importlib.machinery.EXTENSION_SUFFIXES

   認識されている拡張モジュールのファイル接尾辞を表す文字列のリストで
   す。

   Added in version 3.3.

importlib.machinery.all_suffixes()

   標準のインポート機構によって認識されているすべてのファイル接尾辞を
   表す文字列の組み合わせられたリストを返します。これが役立つのは、あ
   るファイルシステムパスがモジュールを参照する可能性があるかだけを知
   りたくて、そのモジュールの種類を詳しく知る必要はないコード (例えば
   "inspect.getmodulename()") です。

   Added in version 3.3.

class importlib.machinery.BuiltinImporter

   組み込みモジュールの *importer* です。 すべての既知の組み込みモジュ
   ールは "sys.builtin_module_names" に列挙されています。 このクラスは
   "importlib.abc.MetaPathFinder" および "importlib.abc.InspectLoader"
   抽象基底クラスを実装します。

   インスタンス化の必要性を軽減するため、このクラスにはクラスメソッド
   だけが定義されています。

   バージョン 3.5 で変更: **PEP 489** の一環として、組み込みインポータ
   ーは "Loader.create_module" と "Loader.exec_module" を実装するよう
   になりました。

class importlib.machinery.FrozenImporter

   フリーズされたモジュールの *インポーター* です。このクラスは
   "importlib.abc.MetaPathFinder" および "importlib.abc.InspectLoader"
   抽象基底クラスを実装します。

   インスタンス化の必要性を軽減するため、このクラスにはクラスメソッド
   だけが定義されています。

   バージョン 3.4 で変更: "create_module()" と "exec_module()" メソッ
   ドを追加しました。

class importlib.machinery.WindowsRegistryFinder

   Windows レジストリで宣言されたモジュールの *finder* です。このクラ
   スは "importlib.abc.MetaPathFinder" 抽象基底クラスを実装します。

   インスタンス化の必要性を軽減するため、このクラスにはクラスメソッド
   だけが定義されています。

   Added in version 3.3.

   バージョン 3.6 で非推奨: 代わりに "site" の設定を使ってください。
   Python の将来のバージョンでは、デフォルトでこのファインダーが使えな
   くなるかもしれません。

class importlib.machinery.PathFinder

   "sys.path" およびパッケージの "__path__" 属性の *Finder* です。この
   クラスは "importlib.abc.MetaPathFinder" 抽象基底クラスを実装します
   。

   インスタンス化の必要性を軽減するため、このクラスにはクラスメソッド
   だけが定義されています。

   classmethod find_spec(fullname, path=None, target=None)

      "sys.path" または定義されていれば *path* から、 *fullname* で指
      定されたモジュールの *スペック* の検索を試みるクラスメソッドです
      。検索されるそれぞれのパスエントリに対して
      "sys.path_importer_cache" が検査されます。偽でないオブジェクトが
      見つかれば、それが目的のモジュールを検索するための *パスエントリ
      ・ファインダー* として使われます。 "sys.path_importer_cache" に
      目的のエントリが見つからなければ、パスエントリに対するファインダ
      ーが "sys.path_hooks" から検索され、見つかれば、それが
      "sys.path_importer_cache" に保管されるとともに、モジュールについ
      て問い合わせられます。それでもファインダーが見つからなければ
      "None" が保管され、また返されます。

      Added in version 3.4.

      バージョン 3.5 で変更: もしカレントワーキングディレクトリ -- 空
      の文字列によって表されている -- がすでに有効でなければ、 "None"
      が返されますが値は "sys.path_importer_cache" にキャッシュされま
      せん。

   classmethod invalidate_caches()

      "sys.path_importer_cache" に保存されたファインダーのうち、このメ
      ソッドを定義しているすべてのファインダーで
      "importlib.abc.PathEntryFinder.invalidate_caches()" を呼び出しま
      す。 一方、"sys.path_importer_cache" の値が "None" のエントリー
      は削除します。

      バージョン 3.7 で変更: "sys.path_importer_cache" の "None" のエ
      ントリーを削除するようになりました。

   バージョン 3.4 で変更: "''" (すなわち空の文字列) に対してはカレント
   ワーキングディレクトリとともに "sys.path_hooks" のオブジェクトを呼
   び出します。

class importlib.machinery.FileFinder(path, *loader_details)

   ファイルシステムからの結果をキャッシュする
   "importlib.abc.PathEntryFinder" の具象実装です。

   *path* 引数は、このファインダーが検索を担当するディレクトリです。

   *loader_details* 引数は、可変個の 2 要素タプルで、それぞれがローダ
   ーとローダーが認識するファイル接尾辞のシーケンスとを含みます。ロー
   ダーは、呼び出し可能でモジュール名と見つかったファイルのパスとの 2
   引数を受け付けることを期待されます。

   ファインダーは必要に応じてディレクトリの内容をキャッシュし、モジュ
   ールを検索するたびに stat を呼び出して、キャッシュが古くなっていな
   いか確認します。 キャッシュの古さの判定は、オペレーティングシステム
   が提供するファイルシステムの状態情報の粒度に依存します。 そのため、
   モジュールを検索し、新しいファイルを作成し、そのファイルが表すモジ
   ュールを検索するという一連の操作では、競合状態が起こる可能性があり
   ます。 これらの操作が stat の時間分解能に収まるほど短時間で起こると
   、モジュールの検索は失敗します。 これを防ぐには、モジュールを動的に
   作成した際に必ず "importlib.invalidate_caches()" を呼び出してくださ
   い。

   Added in version 3.3.

   path

      ファインダーが検索するパスです。

   find_spec(fullname, target=None)

      "path" 内で *fullname* を扱うスペックの探索を試みます。

      Added in version 3.4.

   invalidate_caches()

      内部キャッシュを完全に消去します。

   classmethod path_hook(*loader_details)

      "sys.path_hooks" で使うクロージャを返すクラスメソッドです。 クロ
      ージャは、直接渡されたパス引数と、間接的に渡された
      *loader_details* を使って、"FileFinder" インスタンスを返します。

      クロージャへの引数が存在するディレクトリでなければ、
      "ImportError" が送出されます。

class importlib.machinery.NamespacePath(name, path, path_finder)

   *名前空間パッケージ* のパス ("module.__path__") を表します。

   "__path__" の値が参照されると、必要に応じて再計算されます。 これに
   よりグローバルな状態 ("sys.modules") との整合性を保ちます。

   *name* 引数は名前空間モジュールの名前です。

   *path* 引数はパスの初期値です。

   *path_finder* 引数は、パスの値を再計算するための呼び出し可能オブジ
   ェクトです。 シグネチャは
   "importlib.abc.MetaPathFinder.find_spec()" と同じです。

   親の "module.__path__" 属性が更新されると、パスの値を再計算します。

   親モジュールが "sys.modules" にない場合、"ModuleNotFoundError" を送
   出します。

   トップレベルのモジュールでは、親モジュールのパスに相当するものは
   "sys.path" です。

   注釈:

     "PathFinder.invalidate_caches()" は "NamespacePath" を無効化し、
     次にアクセスされた際にパスの値を必ず再計算させます。

   Added in version 3.15.

class importlib.machinery.SourceFileLoader(fullname, path)

   "importlib.abc.FileLoader" を継承し、その他いくつかのメソッドの具象
   実装を提供する、 "importlib.abc.SourceLoader" の具象実装です。

   Added in version 3.3.

   バージョン 3.15 で変更: "load_module()" メソッドを削除しました。

   name

      このローダーが扱うモジュールの名前です。

   path

      ソースファイルへのパスです。

   is_package(fullname)

      "path" がパッケージを表すとき "True" を返します。

   path_stats(path)

      "importlib.abc.SourceLoader.path_stats()" の具象実装です。

   set_data(path, data)

      "importlib.abc.SourceLoader.set_data()" の具象実装です。

class importlib.machinery.SourcelessFileLoader(fullname, path)

   バイトコードファイル (すなわちソースコードファイルが存在しない) を
   インポートできる "importlib.abc.FileLoader" の具象実装です。

   注意として、バイトコードを直接使う (つまりソースコードファイルがな
   い) と、そのモジュールはすべての Python 実装では使用できないし、新
   しいバージョンの Python ではバイトコードフォーマットが変更されてい
   たら使用できません。

   Added in version 3.3.

   バージョン 3.15 で変更: "load_module()" メソッドを削除しました。

   name

      ローダーが扱うモジュールの名前です。

   path

      バイトコードファイルへのパスです。

   is_package(fullname)

      そのモジュールがパッケージであるかを "path" に基づいて決定します
      。

   get_code(fullname)

      "path" から作成された "name" のコードオブジェクトを返します。

   get_source(fullname)

      このローダーを使う場合、バイトコードファイルにはソースがないため
      "None" を返します。

class importlib.machinery.ExtensionFileLoader(fullname, path)

   拡張モジュールのための "importlib.abc.ExecutionLoader" の具象実装で
   す。

   *fullname* 引数はローダーがサポートするモジュールの名前を指定します
   。*path* 引数は拡張モジュールのファイルへのパスです。

   複数フェーズの初期化 (**PEP 489** を参照) を実装していない拡張モジ
   ュールは、通常なら正常にインポートできても、デフォルトではサブイン
   タープリタへのインポートに失敗します。

   Added in version 3.3.

   バージョン 3.12 で変更: サブインタープリタで使うには、複数フェーズ
   の初期化が必要になりました。

   name

      ローダーがサポートするモジュールの名前です。

   path

      拡張モジュールへのパスです。

   create_module(spec)

      与えられたスペックから **PEP 489** に従ってモジュールオブジェク
      トを作成します。

      Added in version 3.5.

   exec_module(module)

      与えられたモジュールオブジェクトを **PEP 489** に従って初期化し
      ます。

      Added in version 3.5.

   is_package(fullname)

      "EXTENSION_SUFFIXES" に基づき、ファイルパスがパッケージの
      "__init__" モジュールを指す場合に "True" を返します。

   get_code(fullname)

      拡張モジュールにはコードオブジェクトがないため "None" を返します
      。

   get_source(fullname)

      拡張モジュールにはソースコードがないため "None" を返します。

   get_filename(fullname)

      "path" を返します。

      Added in version 3.4.

class importlib.machinery.NamespaceLoader(name, path, path_finder)

   名前空間パッケージ向けの "importlib.abc.InspectLoader" の具体的な実
   装です。 非公開クラスの別名であり、名前空間パッケージの
   "__loader__" 属性を調べる目的に限って公開されています。

      >>> from importlib.machinery import NamespaceLoader
      >>> import my_namespace
      >>> isinstance(my_namespace.__loader__, NamespaceLoader)
      True
      >>> import importlib.abc
      >>> isinstance(my_namespace.__loader__, importlib.abc.Loader)
      True

   Added in version 3.11.

class importlib.machinery.ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)

   モジュールのインポートシステムに関する状態の仕様です。 通常はモジュ
   ールの "__spec__" 属性として公開されます。 これらの属性の多くはモジ
   ュールから直接取得することもでき、例えば "module.__spec__.origin ==
   module.__file__" が成り立ちます。 ただし、通常は *値* が等しくても
   、2 つのオブジェクト間で同期は行われないため、異なる場合もあります
   。 例えば、実行時にモジュールの "__file__" を更新しても、モジュール
   の "__spec__.origin" には自動的に反映されず、逆も同様です。

   Added in version 3.4.

   name

      モジュールの完全修飾名です ("module.__name__" を参照)。 *ファイ
      ンダー* は、常にこの属性を空でない文字列に設定する必要があります
      。

   loader

      モジュールをロードする *ローダー* です ("module.__loader__" を参
      照)。 *ファインダー* は常にこの属性を設定する必要があります。

   origin

      *ローダー* がモジュールのロードに使う場所です ("module.__file__"
      を参照)。 例えば、".py" ファイルからロードするモジュールではファ
      イル名です。 *ファインダー* は、常に *ローダー* が使える意味のあ
      る値をこの属性に設定する必要があります。 名前空間パッケージなど
      、該当する場所がない例外的な場合には "None" に設定してください。

   submodule_search_locations

      パッケージのサブモジュールを検索する場所を列挙した、文字列の *シ
      ーケンス* です ("module.__path__" を参照)。 空の場合もありますが
      、通常はディレクトリが 1 つだけ含まれます。

      モジュールがパッケージであることをインポートシステムに示すには、
      *ファインダー* は、この属性を空でもよいのでシーケンスに設定する
      必要があります。 パッケージでないモジュールでは "None" にしてく
      ださい。 名前空間パッケージでは、後で特殊なオブジェクトが自動的
      に設定されます。

   loader_state

      *ファインダー* は、この属性に、モジュールのロードに使う追加のモ
      ジュール固有データを格納したオブジェクトを設定できます。 それ以
      外の場合は "None" に設定してください。

   cached

      モジュールのコードをコンパイルしたファイルの名前です。 *ファイン
      ダー* は常にこの属性を設定する必要がありますが、コンパイル済みコ
      ードの保存が不要なモジュールでは "None" にできます。

   parent

      (読み取り専用) モジュールが属するパッケージの完全修飾名です (ト
      ップレベルのモジュールでは空文字列)。 "module.__package__" を参
      照してください。 モジュール自体がパッケージであれば、"name" と同
      じです。

   has_location

      スペックの "origin" がロード可能な場所を指す場合は "True"、それ
      以外は "False" です。 この値は "origin" の解釈方法と、モジュール
      の "__file__" の設定方法に影響します。

class importlib.machinery.AppleFrameworkLoader(name, path)

   フレームワーク形式の拡張モジュールを読み込み事ができる、特殊な
   "importlib.machinery.ExtensionFileLoader" です。

   iOS App Store との互換性のため、 iOS アプリの *すべての* バイナリモ
   ジュールは、パッケージ化されたアプリの "Frameworks" フォルダーに保
   存された、適切なメタデータ付きのフレームワークにある動的ライブラリ
   である必要があります。フレームワークごとにバイナリは一つだけで、
   Frameworks フォルダーの外に実行可能バイナリデータを設置することはで
   きません。

   この要件に対応するため、iOS で実行する拡張モジュールのバイナリは、
   "sys.path" 上の ".so" ファイルでは *なく*、個別の独立したフレームワ
   ークとしてパッケージ化されます。 これらのフレームワークを検出するた
   め、このローダーは ".fwork" 拡張子に対して登録されます。 ".fwork"
   ファイルは、"sys.path" 上のバイナリの元の場所に置くプレースホルダー
   として機能します。 ".fwork" ファイルには、"Frameworks" フォルダ内に
   ある実際のバイナリのパスを、アプリバンドルからの相対パスで記録しま
   す。 フレームワークにまとめたバイナリから元の場所を解決できるよう、
   フレームワークには ".origin" ファイルを含め、そこに ".fwork" ファイ
   ルの場所をアプリバンドルからの相対パスで記録する必要があります。

   例えば、"from foo.bar import _whiz" をインポートする場合を考えてみ
   ましょう。 "_whiz" がバイナリモジュール
   "sources/foo/bar/_whiz.abi3.so" で実装されており、 "sources" のアプ
   リケーションバンドルからの相対パスが "sys.path" に登録されています
   。このモジュールは
   "Frameworks/foo.bar._whiz.framework/foo.bar._whiz" （フレームワーク
   名はモジュールの完全なインポートパスから命名されています）として、
   "Info.plist" ファイルをバイナリをフレームワークとして識別する
   ".framework" ディレクトリ内に設置して配布しなければなりません。
   "foo.bar._whiz" モジュールは、元の場所で、
   "Frameworks/foo.bar._whiz/foo.bar._whiz" のパスを含む
   "sources/foo/bar/_whiz.abi3.fwork" マーカーファイルに記述されます。
   また、フレームワークは、 ".fwork" へのパスを含む
   "Frameworks/foo.bar._whiz.framework/foo.bar._whiz.origin" も含まな
   ければなりません。

   このローダーでモジュールをロードすると、モジュールの "__file__" は
   ".fwork" ファイルの場所になります。 そのため、モジュールの
   "__file__" を基点としてファイルシステムをたどるコードを使えます。
   ただし、スペックの origin は ".framework" フォルダ内の *実際の* バ
   イナリの場所を指します。

   "PYTHONPATH" 内のどこにある ".so" ファイルも、"Frameworks" フォルダ
   内のフレームワークに変換し、".fwork" と ".origin" ファイルを作成す
   る責任は、アプリをビルドする Xcode プロジェクトにあります。 変換に
   は、モジュールファイルの拡張子の除去、フレームワークのメタデータの
   追加、生成されたフレームワークへの署名も含まれます。 通常は Xcode
   プロジェクトのビルドステップで行います。 このビルドステップの作成方
   法は iOS のドキュメントを参照してください。

   Added in version 3.13.

   利用可能な環境: iOS.

   name

      ローダーがサポートするモジュールの名前です。

   path

      拡張モジュールの ".fwork" ファイルへのパス。


"importlib.util" -- インポーター向けのユーティリティ
====================================================

**ソースコード:** Lib/importlib/util.py

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

このモジュールには、 *インポーター* の構築を助ける様々なオブジェクトが
あります。

importlib.util.MAGIC_NUMBER

   バイトコードバージョン番号を表しているバイト列。バイトコードのロー
   ド／書き込みについてヘルプが必要なら "importlib.abc.SourceLoader"
   を参照してください。

   Added in version 3.4.

importlib.util.cache_from_source(path, *, optimization=None)

   ソースの *path* に対応するバイトコンパイル済みファイルへの、**PEP
   3147**/**PEP 488** に従うパスを返します。 例えば、*path* が
   "/foo/bar/baz.py" の場合、Python 3.2 での戻り値は
   "/foo/bar/__pycache__/baz.cpython-32.pyc" です。 "cpython-32" とい
   う文字列は現在のマジックタグに由来します
   ("sys.implementation.cache_tag" を参照。 定義されていなければ
   "NotImplementedError" を送出します)。

   *optimization* パラメータは、バイトコードファイルの最適化レベルを指
   定するために使われます。空文字列は最適化しないことを表します。した
   がって、 *optimization* が "''" のとき "/foo/bar/baz.py" に対して
   "/foo/bar/__pycache__/baz.cpython-32.pyc" というバイトコードパスが
   返ります。 "None" にするとインタープリタの最適化レベルが使われます
   。それ以外では値の文字列表現が使われます。したがって、
   *optimization* が "2" のとき  "/foo/bar/baz.py" に対して
   "/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc" というバイトコード
   パスが返ります。 *optimization* の文字列表現は英数字だけが可能で、
   そうでなければ "ValueError" が上げられます。

   Added in version 3.4.

   バージョン 3.5 で変更: *optimization* パラメータが追加され、
   *debug_override* パラメータは deprecated になりました。

   バージョン 3.6 で変更: *path-like object* を受け入れるようになりま
   した。

   バージョン 3.15 で変更: *debug_override* 引数を削除しました。

importlib.util.source_from_cache(path)

   **PEP 3147** のファイル名への *path* を受け取り、対応するソースコー
   ドファイルのパスを返します。 例えば、*path* が
   "/foo/bar/__pycache__/baz.cpython-32.pyc" の場合、"/foo/bar/baz.py"
   を返します。 *path* は存在しなくてもかまいませんが、**PEP 3147** ま
   たは **PEP 488** の形式に従っていなければ "ValueError" を送出します
   。 "sys.implementation.cache_tag" が定義されていなければ
   "NotImplementedError" を送出します。

   Added in version 3.4.

   バージョン 3.6 で変更: *path-like object* を受け入れるようになりま
   した。

importlib.util.decode_source(source_bytes)

   与えられたソースコードを表すバイト列をデコードして、文字列としてそ
   れを一般的な改行形式 (universal newlines) で返します
   ("importlib.abc.InspectLoader.get_source()" で要求されるように)。

   Added in version 3.4.

importlib.util.resolve_name(name, package)

   相対的なモジュール名を解決して絶対的なものにします。

   **name** の先頭にドットがなければ、単に **name** が返されます。これ
   により、例えば "importlib.util.resolve_name('sys',
   __spec__.parent)" を使うときに **package** 変数が必要かどうかを確認
   する必要がなくなります。

   **name** が相対的なモジュール名であるにもかかわらず **package** が
   偽値 (例えば "None" や空文字列) ならば、 "ImportError" が送出されま
   す。相対的な名前がそれを含むパッケージから抜け出る (例えば "spam"
   パッケージ内から "..bacon" を要求する) 場合にも "ImportError" が送
   出されます。

   Added in version 3.3.

   バージョン 3.9 で変更: インポート文との一貫性を高めるため、不正な相
   対インポートに対して "ValueError" ではなく "ImportError" を送出する
   ようになりました。

importlib.util.find_spec(name, package=None)

   モジュールの *スペック* を検索します。 必要に応じて、指定した
   **package** 名を基準にした相対名を使えます。 モジュールが
   "sys.modules" にあれば、"sys.modules[name].__spec__" を返します (た
   だし、スペックが "None" か未設定の場合は "ValueError" を送出します)
   。 それ以外の場合は "sys.meta_path" を使って検索します。 スペックが
   見つからなければ "None" を返します。

   **name** がサブモジュールを示している  (ドットを含む) 場合、親モジ
   ュールは自動的にインポートされます。

   **name** と **package** は "importlib.import_module()" と同じように
   働きます。

   Added in version 3.4.

   バージョン 3.7 で変更: **package** が実際にはパッケージでない
   ("__path__" 属性がない) 場合、"AttributeError" ではなく
   "ModuleNotFoundError" を送出するようになりました。

importlib.util.module_from_spec(spec)

   **spec** と "spec.loader.create_module" に基づいて新しいモジュール
   を作ります。

   "spec.loader.create_module" が "None" を返さない場合は、既に存在す
   るどの属性もリセットされません。また、 **spec** にアクセスしたり属
   性をモジュールに設定したりする際に "AttributeError" 例外が起きても
   例外は送出されません。

   この関数は、新しいモジュールを作る方法として "types.ModuleType" よ
   りも推奨されます。なぜなら、できるだけ多くのインポートコントロール
   された属性をモジュールに設定するために **spec** が使用されるからで
   す。

   Added in version 3.5.

importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None)

   ローダーに基づいて "ModuleSpec" インスタンスを作成するファクトリー
   関数です。 引数は ModuleSpec と同じ意味です。
   "InspectLoader.is_package" などの利用可能な *ローダー* API を使い、
   スペックに不足している情報を補います。

   Added in version 3.4.

importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)

   ファイルへのパスにもとづいて "ModuleSpec" インスタンスを生成するた
   めのファクトリー関数。不足している情報は、ローダー API を利用してス
   ペックから得られる情報と、モジュールがファイルベースであるという暗
   黙的な情報によって埋められます。

   Added in version 3.4.

   バージョン 3.6 で変更: *path-like object* を受け入れるようになりま
   した。

importlib.util.source_hash(source_bytes)

   *source_bytes* のハッシュをバイト列として返します。 ハッシュベース
   の ".pyc" ファイルは、対応するソースファイルの内容の
   "source_hash()" をヘッダに埋め込みます。

   Added in version 3.7.

importlib.util._incompatible_extension_module_restrictions(*, disable_check)

   拡張モジュールの互換性チェックを一時的に省略できるコンテキストマネ
   ージャです。 デフォルトではチェックが有効で、単一フェーズの初期化を
   使うモジュールをサブインタープリタにインポートすると失敗します。 ま
   た、複数フェーズの初期化を使うモジュールでも、インタープリタごとの
   GIL を明示的にサポートしていなければ、独自の GIL を持つインタープリ
   タへのインポートは失敗します。

   この関数は特殊なケースに対応するためのものであり、そのケースも将来
   なくなる可能性があります。 探していた機能とは違う可能性が高いことに
   注意してください。

   複数フェーズの初期化 (**PEP 489**) の基本インターフェースを実装し、
   複数インタープリタ (またはインタープリタごとの GIL) のサポートを偽
   って申告することでも、この関数と同じ効果を得られます。

   警告:

     この関数でチェックを無効にすると、予期しない動作やクラッシュさえ
     引き起こす場合があります。 拡張モジュールの開発中に限って使ってく
     ださい。

   Added in version 3.12.

class importlib.util.LazyLoader(loader)

   モジュールの属性がアクセスされるまで、そのモジュールのローダーの実
   行を遅延するクラスです。

   このクラスは、モジュールに使う型を制御する必要があるため、
   "exec_module()" を定義したローダーで *のみ* 動作します。 同じ理由で
   、ローダーの "create_module()" メソッドは、"None" か、"__class__"
   属性を変更でき、かつ *スロット* を使わない型のオブジェクトを返す必
   要があります。 また、"sys.modules" に置いたオブジェクトを別のオブジ
   ェクトに差し替えるモジュールでは動作しません。 インタープリタ全体の
   モジュールへの参照を安全かつ正しく置き換える方法がないためです。 こ
   のような差し替えを検出すると "ValueError" を送出します。

   注釈:

     起動時間が重要なプロジェクトでは、もし決して使われないモジュール
     があれば、このクラスを使ってモジュールをロードするコストを最小化
     できるかもしれません。スタートアップ時間が重要でないプロジェクト
     では、遅延されたロードの際に発生して文脈の外で起こるエラーメッセ
     ージのため、このクラスの使用は **著しく** 推奨されません。

   Added in version 3.5.

   バージョン 3.6 で変更: "create_module()" を呼び出すようになり、
   "importlib.machinery.BuiltinImporter" と
   "importlib.machinery.ExtensionFileLoader" に対する互換性の警告を削
   除しました。

   classmethod factory(loader)

      遅延ローダを生成する callable を返すクラスメソッド。これは、ロー
      ダーをインスタンスとしてではなくクラスとして渡すような状況におい
      て使われることを意図しています。

         suffixes = importlib.machinery.SOURCE_SUFFIXES
         loader = importlib.machinery.SourceFileLoader
         lazy_loader = importlib.util.LazyLoader.factory(loader)
         finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))


使用例
======


プログラムからのインポート
--------------------------

プログラムからモジュールをインポートするには、
"importlib.import_module()" を使ってください。

   import importlib

   itertools = importlib.import_module('itertools')


モジュールがインポートできるか確認する
--------------------------------------

インポートを実際に行わずに、あるモジュールがインポートできるかを知る必
要がある場合は、 "importlib.util.find_spec()" を使ってください。

"name" がサブモジュールを指す (ドットを含む) 場合、
"importlib.util.find_spec()" は親モジュールをインポートします。

   import importlib.util
   import sys

   # 説明のための例。
   name = 'itertools'

   if name in sys.modules:
       print(f"{name!r} already in sys.modules")
   elif (spec := importlib.util.find_spec(name)) is not None:
       # 実際にインポートする場合...
       module = importlib.util.module_from_spec(spec)
       sys.modules[name] = module
       spec.loader.exec_module(module)
       print(f"{name!r} has been imported")
   else:
       print(f"can't find the {name!r} module")


ソースファイルから直接インポートする
------------------------------------

この方法は注意して使ってください。 "sys.path" を検索する代わりにファイ
ルパスを直接指定し、インポート文に近い動作をするものです。 まずは、正
式なモジュールが必要なら "sys.path" を変更する、Python ファイルを実行
した結果のグローバル名前空間でよければ "runpy.run_path()" を使うなど、
別の方法を検討してください。

パスから Python ソースファイルを直接インポートするには、次のようにしま
す。

   import importlib.util
   import sys


   def import_from_path(module_name, file_path):
       spec = importlib.util.spec_from_file_location(module_name, file_path)
       module = importlib.util.module_from_spec(spec)
       sys.modules[module_name] = module
       spec.loader.exec_module(module)
       return module


   # 説明のための例にすぎない (`json` を選んだことに特別な意味はない)。
   import json
   file_path = json.__file__
   module_name = json.__name__

   # `import json` と同様の結果。
   json = import_from_path(module_name, file_path)


遅延インポートの実装
--------------------

以下の例は遅延インポートを実装する方法を示します。

   >>> import importlib.util
   >>> import sys
   >>> def lazy_import(name):
   ...     spec = importlib.util.find_spec(name)
   ...     loader = importlib.util.LazyLoader(spec.loader)
   ...     spec.loader = loader
   ...     module = importlib.util.module_from_spec(spec)
   ...     sys.modules[name] = module
   ...     loader.exec_module(module)
   ...     return module
   ...
   >>> lazy_typing = lazy_import("typing")
   >>> #lazy_typing は実際のモジュールオブジェクトだが、
   >>> #まだメモリにロードされていない。
   >>> lazy_typing.TYPE_CHECKING
   False


インポーターのセットアップ
--------------------------

インポートを大幅にカスタマイズする場合、通常は *インポーター* を実装し
ます。 そのためには、*ファインダー* と *ローダー* の両方を扱います。
ファインダーには *メタパスファインダー* と *パスエントリファインダー*
の 2 種類があり、必要に応じて選べます。 前者は "sys.meta_path" に登録
するものです。 後者は "sys.path_hooks" にある *パスエントリフック* が
"sys.path" の各要素に対して処理し、必要に応じて作成するものです。 この
例では、独自のインポーターをインポート時に使わせるために登録する方法を
示します (インポーター自体の作成方法は、このパッケージで定義された適切
なクラスのドキュメントを読んでください)。

   import importlib.machinery
   import sys

   # 説明のための例。
   SpamMetaPathFinder = importlib.machinery.PathFinder
   SpamPathEntryFinder = importlib.machinery.FileFinder
   loader_details = (importlib.machinery.SourceFileLoader,
                     importlib.machinery.SOURCE_SUFFIXES)

   # メタパスファインダーを設定する。
   # 優先順位に応じて、リスト内の適切な位置にファインダーを登録する。
   sys.meta_path.append(SpamMetaPathFinder)

   # パスエントリファインダーを設定する。
   # 優先順位に応じて、リスト内の適切な位置にパスフックを登録する。
   sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))


"importlib.import_module()" に近い実装
--------------------------------------

インポート自体が Python コードで実装されているため、インポート機構の大
部分を importlib を通じて公開できます。 以下では
"importlib.import_module()" に近い実装を示し、importlib が公開するさま
ざまな API の使い方を説明します。

   import importlib.util
   import sys

   def import_module(name, package=None):
       """インポートに近い動作をする実装。"""
       absolute_name = importlib.util.resolve_name(name, package)
       try:
           return sys.modules[absolute_name]
       except KeyError:
           pass

       path = None
       if '.' in absolute_name:
           parent_name, _, child_name = absolute_name.rpartition('.')
           parent_module = import_module(parent_name)
           path = parent_module.__spec__.submodule_search_locations
       for finder in sys.meta_path:
           spec = finder.find_spec(absolute_name, path)
           if spec is not None:
               break
       else:
           msg = f'No module named {absolute_name!r}'
           raise ModuleNotFoundError(msg, name=absolute_name)
       module = importlib.util.module_from_spec(spec)
       sys.modules[absolute_name] = module
       spec.loader.exec_module(module)
       if path is not None:
           setattr(parent_module, child_name, module)
       return module
