31.4. "runpy" --- Python モジュールの位置特定と実行
***************************************************

**ソースコード:** Lib/runpy.py

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

"runpy" モジュールは Python のモジュールをインポートせずにその位置を特
定したり実行したりするのに使われます。その主な目的はファイルシステムで
はなく Python のモジュール名前空間を使って位置を特定したスクリプトの実
行を可能にする "-m" コマンドラインスイッチを実装することです。

これはサンドボックスモジュール *ではない* ことに注意してください。すべ
てのコードは現在のプロセスで実行され、あらゆる副作用 (たとえば他のモジ
ュールのキャッシュされたインポート等) は関数から戻った後にそのまま残り
ます。

さらに、 "runpy" 関数から戻った後で、実行されたコードによって定義され
た任意の関数およびクラスが正常に動作することは保証されません。この制限
が受け入れられないユースケースでは、 "importlib" がこのモジュールより
適切な選択となるでしょう。

"runpy" モジュールは2つの関数を提供しています:

runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)

   指定されたモジュールのコードを実行し、実行後のモジュールグローバル
   辞書を返します。モジュールのコードはまず標準インポート機構(詳細は
   **PEP 302** を参照) を使ってモジュールの位置を特定され、まっさらな
   モジュール名前空間で実行されます。

   The *mod_name* argument should be an absolute module name. If the
   module name refers to a package rather than a normal module, then
   that package is imported and the "__main__" submodule within that
   package is then executed and the resulting module globals
   dictionary returned.

   オプションの辞書型引数 *init_globals* はコードを実行する前にモジュ
   ールグローバル辞書に前もって必要な設定しておくのに使われます。与え
   られた辞書は変更されません。その辞書の中に以下に挙げる特別なグロー
   バル変数が定義されていたとしても、それらの定義は "run_module()" 関
   数によってオーバーライドされます。

   特別なグローバル変数 "__name__", "__spec__", "__file__",
   "__cached__", "__loader__", "__package__" はモジュールコードが実行
   される前にグローバル辞書にセットされます。(この変数群は修正される最
   小セットです。これ以外の変数もインタプリタの実装の詳細として暗黙的
   に設定されるかもしれません)。

   "__name__" は、オプション引数 *run_name* が "None" でない場合、指定
   されたモジュールがパッケージであれば "mod_name + '.__main__'" に、
   そうでなければ *mod_name* 引数の値がセットされます。

   "__spec__" will be set appropriately for the *actually* imported
   module (that is, "__spec__.name" will always be *mod_name* or
   "mod_name + '.__main__", never *run_name*).

   "__file__", "__cached__", "__loader__" and "__package__" are set as
   normal based on the module spec.

   引数 *alter_sys* が与えられて "True" に評価されるならば、
   "sys.argv[0]" は "__file__" の値で更新され "sys.modules[__name__]"
   は実行されるモジュールの一時的モジュールオブジェクトで更新されます
   。 "sys.argv[0]" と "sys.modules[__name__]" はどちらも関数が処理を
   戻す前にもとの値に復旧します。

   この "sys" に対する操作はスレッドセーフではないということに注意して
   ください。他のスレッドは部分的に初期化されたモジュールを見たり、入
   れ替えられた引数リストを見たりするかもしれません。この関数をスレッ
   ド化されたコードから起動するときは "sys" モジュールには手を触れない
   ことが推奨されます。

   参考: コマンドラインから、 "-m" オプションを与えることで同じ機能を実現
       出来ます。

   バージョン 3.1 で変更: "__main__" サブモジュールを検索することによ
   ってパッケージを実行する機能が追加されました。

   バージョン 3.2 で変更: "__cached__" グローバル変数が追加されました
   (**PEP 3147** を参照)。

   バージョン 3.4 で変更: Updated to take advantage of the module spec
   feature added by **PEP 451**. This allows "__cached__" to be set
   correctly for modules run this way, as well as ensuring the real
   module name is always accessible as "__spec__.name".

runpy.run_path(file_path, init_globals=None, run_name=None)

   指定されたファイルシステム上の場所にあるコードを実行して、結果とし
   てそのモジュールグローバル辞書を返します。通常の CPython 実行時にコ
   マンドラインで指定するスクリプト名と同じく、指定できるパスは Python
   ソースファイル、コンパイルされたバイトコードファイル、もしくは
   "__main__" モジュールを含む有効な sys.path エントリ(例: トップレベ
   ルに "__main__.py" ファイルを持つ zip ファイル)です。

   シンプルなスクリプトを指定した場合は、指定されたコードはシンプルに
   新しいモジュール名前空間で実行されます。有効な sys.path エントリ (
   一般的には zip ファイルかディレクトリ) を指定した場合は、最初にその
   エントリが "sys.path" の先頭に追加されます。次に更新した "sys.path"
   を元に "__main__" モジュールを検索して実行します。指定された場所に
   "__main__" モジュールが無かった時、 "sys.path" のどこか他のエントリ
   に存在する別の "__main__" を実行してしまう可能性があることに注意し
   てください。

   オプションの辞書型引数 *init_globals* はコードを実行する前にモジュ
   ールグローバル辞書に前もって必要な設定しておくのに使われます。与え
   られた辞書は変更されません。その辞書の中に以下に挙げる特別なグロー
   バル変数が定義されていたとしても、それらの定義は "run_path()" 関数
   によってオーバーライドされます。

   特別なグローバル変数 "__name__", "__spec__", "__file__",
   "__cached__", "__loader__", "__package__" はモジュールコードが実行
   される前にグローバル辞書にセットされます。(この変数群は修正される最
   小セットです。これ以外の変数もインタプリタの実装の詳細として暗黙的
   に設定されるかもしれません)。

   "__name__" は、オプション引数 *run_name* が "None" でない場合、
   *run_name* に設定され、それ以外の場合は "'<run_path>'" に設定されま
   す。

   If the supplied path directly references a script file (whether as
   source or as precompiled byte code), then "__file__" will be set to
   the supplied path, and "__spec__", "__cached__", "__loader__" and
   "__package__" will all be set to "None".

   If the supplied path is a reference to a valid sys.path entry, then
   "__spec__" will be set appropriately for the imported "__main__"
   module (that is, "__spec__.name" will always be "__main__").
   "__file__", "__cached__", "__loader__" and "__package__" will be
   set as normal based on the module spec.

   "sys" モジュールに対していくつかの変更操作が行われます。まず、
   "sys.path" が上記のように修正されます。 "sys.argv[0]" は
   "file_path" に更新され、 "sys.modules[__name__]" は実行されるモジュ
   ールのための一時モジュールオブジェクトに更新されます。 "sys" の要素
   に対する全ての変更は、この関数から戻る前に元に戻されます。

   "run_module()" と違い、 "sys" に対する変更はオプションではありませ
   ん。これらの変更は sys.path エントリの実行に必要不可欠だからです。
   スレッドセーフ性に関する制限はこの関数にも存在します。この関数をマ
   ルチスレッドプログラムから実行する場合は、 import lock によりシリア
   ライズして実行するか、別プロセスに委譲してください。

   参考: コマンドラインから インターフェイスオプション で同じ機能を使えま
       す ("python path/to/script")。

   バージョン 3.2 で追加.

   バージョン 3.4 で変更: Updated to take advantage of the module spec
   feature added by **PEP 451**. This allows "__cached__" to be set
   correctly in the case where "__main__" is imported from a valid
   sys.path entry rather than being executed directly.

参考:

  **PEP 338** - モジュールをスクリプトとして実行する
     Nick Coghlan によって書かれ実装された PEP。

  **PEP 366** - main モジュールの明示的な相対インポート
     Nick Coghlan によって書かれ実装された PEP。

  **PEP 451** -- A ModuleSpec Type for the Import System
     PEP written and implemented by Eric Snow

  コマンドラインと環境 - CPython コマンドライン詳細

  "importlib.import_module()" 関数
