# `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__]` はどちらも関数が処理を戻す前にもとの値に復旧します。

  Note that this manipulation of `sys` is not thread-safe. Other threads may see the partially initialised module, as well as the altered list of arguments. It is recommended that the `sys` module be left alone when invoking this function from threaded code.

  参考

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

  バージョン 3.1 で変更: Added ability to execute packages by looking for a `__main__` submodule.

  バージョン 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`.

  バージョン 3.12 で変更: The setting of `__cached__`, `__loader__`, and `__package__` are deprecated. See `ModuleSpec` for alternatives.

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

  Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a compiled bytecode file or a valid `sys.path` entry containing a `__main__` module (e.g. a zipfile containing a top-level `__main__.py` file).

  For a simple script, the specified code is simply executed in a fresh module namespace. For a valid `sys.path` entry (typically a zipfile or directory), the entry is first added to the beginning of `sys.path`. The function then looks for and executes a `__main__` module using the updated path. Note that there is no special protection against invoking an existing `__main__` entry located elsewhere on `sys.path` if there is no such module at the specified location.

  オプションの辞書型引数 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.

  A number of alterations are also made to the `sys` module. Firstly, `sys.path` may be altered as described above. `sys.argv[0]` is updated with the value of `path_name` and `sys.modules[__name__]` is updated with a temporary module object for the module being executed. All modifications to items in `sys` are reverted before the function returns.

  Note that, unlike `run_module()`, the alterations made to `sys` are not optional in this function as these adjustments are essential to allowing the execution of `sys.path` entries. As the thread-safety limitations still apply, use of this function in threaded code should be either serialised with the import lock or delegated to a separate process.

  参考

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

  Added in version 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.

  バージョン 3.12 で変更: The setting of `__cached__`, `__loader__`, and `__package__` are deprecated.

参考

PEP 338 - モジュールをスクリプトとして実行する

  PEP written and implemented by Nick Coghlan.

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

  PEP written and implemented by Nick Coghlan.

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

  PEP written and implemented by Eric Snow

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

`importlib.import_module()` 関数