# `venv` --- 仮想環境の作成

バージョン 3.3 で追加.

ソースコード: Lib/venv/

`venv` モジュールは、軽量な仮想環境の作成を行います。それぞれの仮想環境は、`site` ディレクトリに独立した Python パッケージの集合を持っています。仮想環境は、ベース Python とも呼ばれる、すでにインストールされている Python の上に作成され、明示的にインストールしたパッケージのみが利用可能となるよう、ベース Python から隔離することもできます。

仮想環境の中から使われると、pip のような一般的なインストールツールは明示的に指定しなくても仮想環境に Python パッケージをインストールします。

Python仮想環境の背景についてより詳しくは PEP 405 を参照してください。

参考

Python Packaging User Guide: Creating and using virtual environments

## 仮想環境の作成

仮想環境 を作成するには `venv` コマンドを実行します:

    python -m venv /path/to/new/virtual/environment

このコマンドを実行すると、ターゲットディレクトリ (および必要なだけの親ディレクトリ) が作成され、その中に `pyvenv.cfg` ファイルが置かれます。 そのファイルの `home` キーはこのコマンドを呼び出した Python のインストール場所を指します (よく使われるターゲットディレクトリの名前は `.venv` です)。 このコマンドはまた、 Python バイナリのコピーまたはシンボリックリンク (のプラットフォームあるいは仮想環境作成時に使われた引数に対して適切な方) を含む `bin` (Windows では `Scripts`) サブディレクトリを作成します。 さらに、 `lib/pythonX.Y/site-packages` (Windows では `Lib\site-packages`) サブディレクトリも (最初は空の状態で) 作成します。指定したディレクトリが存在している場合は、それが再利用されます。

バージョン 3.6 で非推奨: Python 3.3 と 3.4 では仮想環境の作成に `pyvenv` が推奨されていましたが、Python 3.6 で非推奨になりました。

バージョン 3.5 で変更: 仮想環境の作成には、 `venv` の使用が今は推奨されています。

Windows では、 `venv` コマンドは次のように実行します:

    c:\>c:\Python35\python -m venv c:\path\to\myenv

あるいは、 インストールされている Python のために `PATH` 変数や `PATHEXT` 変数が設定してある場合は次のコマンドでも実行できます:

    c:\>python -m venv c:\path\to\myenv

このコマンドを `-h` をつけて実行すると利用できるオプションが表示されます:

    usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
                [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps]
                ENV_DIR [ENV_DIR ...]

    Creates virtual Python environments in one or more target directories.

    positional arguments:
      ENV_DIR               A directory to create the environment in.

    optional arguments:
      -h, --help            show this help message and exit
      --system-site-packages
                            Give the virtual environment access to the system
                            site-packages dir.
      --symlinks            Try to use symlinks rather than copies, when symlinks
                            are not the default for the platform.
      --copies              Try to use copies rather than symlinks, even when
                            symlinks are the default for the platform.
      --clear               Delete the contents of the environment directory if it
                            already exists, before environment creation.
      --upgrade             Upgrade the environment directory to use this version
                            of Python, assuming Python has been upgraded in-place.
      --without-pip         Skips installing or upgrading pip in the virtual
                            environment (pip is bootstrapped by default)
      --prompt PROMPT       Provides an alternative prompt prefix for this
                            environment.
      --upgrade-deps        Upgrade core dependencies: pip setuptools to the
                            latest version in PyPI

    Once an environment has been created, you may wish to activate it, e.g. by
    sourcing an activate script in its bin directory.

バージョン 3.9 で変更: pip と setuptools を PyPI での最新版に更新するには、`--upgrade-deps` オプションを追加してください。

バージョン 3.4 で変更: デフォルトで pip をインストールします。`--without-pip` と `--copies` オプションを追加しました。

バージョン 3.4 で変更: 以前のバージョンでは、対象となるディレクトリが既に存在していた場合は、 `--clear` オプションや `--upgrade` オプションを付けない限りはエラーを送出していました。

注釈

Windows でもシンボリックリンクはサポートされていますが、シンボリックリンクを使うのは推奨されません。 特に注目すべきなのは、ファイルエクスプローラ上で `python.exe` をダブルクリックすると、シンボリックリンクを貪欲に解決し仮想環境を無視するということです。

注釈

Microsoft Windows では、ユーザー向けの実行ポリシーを設定して `Activate.ps1` スクリプトが使えるようにする必要があるかもしれません。 この設定は次の PowerShell コマンドでできます:

PS C:> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

さらに詳しくは About Execution Policies を参照してください。

作成された `pyvenv.cfg` ファイルには、`include-system-site-packages` キーも含まれます。これは `venv` が `--system-site-packages` オプションをつけて実行されたなら `true` で、そうでなければ `false` です。

`--without-pip` オプションが与えられない限り、`pip` を仮想環境でブートするために `ensurepip` が呼ばれます。

`venv` には複数のパスを渡すことができ、その場合はそれぞれのパスに同一の仮想環境が作成されます。

## 仮想環境のしくみ

Python インタプリタが仮想環境で実行しているとき、`sys.prefix` と `sys.exec_prefix` は仮想環境のディレクトリを指し示し、 `sys.base_prefix` と `sys.base_exec_prefix` は仮想環境の作成に使われたベース Python のディレクトリを指し示します。`sys.prefix == sys.base_prefix` を調べれば、現在のインタプリタが仮想環境で実行しているかを判定できます。

A virtual environment may be "activated" using a script in its binary directory (`bin` on POSIX; `Scripts` on Windows). This will prepend that directory to your `PATH`, so that running python will invoke the environment's Python interpreter and you can run installed scripts without having to use their full path. The invocation of the activation script is platform-specific (`<venv>` must be replaced by the path to the directory containing the virtual environment):

プラットフォーム | シェル | 仮想環境を有効化するためのコマンド
--- | --- | ---
POSIX | bash/zsh | `$ source <venv>/bin/activate`
fish | `$ source <venv>/bin/activate.fish`
csh/tcsh | `$ source <venv>/bin/activate.csh`
PowerShell | `$ <venv>/bin/Activate.ps1`
Windows | cmd.exe | `C:\> <venv>\Scripts\activate.bat`
PowerShell | `PS C:\> <venv>\Scripts\Activate.ps1`

バージョン 3.4 で追加: fish and csh activation scripts.

バージョン 3.8 で追加: PowerShell Core のサポートのために POSIX 環境にインストールされた、PowerShell 有効化スクリプト。

Python を呼び出すときに仮想環境の Python インタプリタへのフルパスを指定すれば良いだけなので、仮想環境をアクティベートする 必要 はありません。さらに、仮想環境にインストールされたすべてのスクリプトはアクティベートせずとも実行可能なはずです。

これを達成するため、仮想環境にインストールされたスクリプトは、仮想環境の Python インタプリタを指し示す "shebang" の行を含みます i.e. `#!/<path-to-venv>/bin/python` 。つまり、`PATH` の値に関係なくそのスクリプトはそのインタプリタを使って実行されます。Windows では、"shebang" の行の処理は Windows の Python ランチャ がインストールされていれば可能です。したがって、Windows のエクスプローラのウィンドウで、インストールされたスクリプトをダブルクリックすると、仮想環境をアクティベートしたり `PATH` を編集したりしなくても、正しいインタプリタでスクリプトが実行されるはずです。

仮想環境がアクティベートされると、`VIRTUAL_ENV` 環境変数の値が仮想環境へのパスに設定されます。アクティベートしなくても仮想環境を使うことは可能なため、仮想環境が使われているか否かの判断を `VIRTUAL_ENV` に頼ることはできません。

警告

仮想環境にインストールされたスクリプトは仮想環境がアクティベートされていることを前提とすべきではないため、shebang の行は仮想環境のインタプリタへの絶対パスを含みます。このため、本質的に、仮想環境は一般の場合ポータブルではありません。いつでも仮想環境を再作成できる簡単な方法を持っておくべきです（例えば、`requirements.txt` という requirements ファイルがあれば、仮想環境の `pip` を用いて、`pip install -r requirements.txt` を呼び出すことで、仮想環境が必要とするすべてのパッケージをインストールできます）。何らかの理由で仮想環境を別の場所に移動する必要がある場合は、新しい場所で仮想環境を再作成し、古い場所にある仮想環境を削除してください。仮想環境の親ディレクトリを移動したため仮想環境も移動された場合は、新しい場所で仮想環境を再作成する必要があります。さもなくば、仮想環境にインストールされたソフトウェアが想定通りに動作しない可能性があります。

シェルで `deactivate` と入力することで仮想環境を無効化できます。 厳密な仕組みはプラットフォーム固有であり、内部の実装詳細です (たいていはスクリプトかシェル関数が使われます)。

## API

上述の高水準のメソッドは、サードパーティの仮想環境の作成者が環境の作成を必要に応じてカスタマイズするための機構を提供する簡素な API を利用します。それが `EnvBuilder` クラスです。

class `venv.``EnvBuilder`(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False)

  `EnvBuilder` クラスを実体化するときに、以下のキーワード引数を受け取ります:

  - `system_site_packages` -- 真偽値で、システムの Python の site-packages を仮想環境から利用できるかどうかを示します (デフォルト: `False`)。

  - `clear` -- 真偽値で、真の場合環境を作成する前に既存の対象ディレクトリの中身を削除します。

  - `symlinks` -- 真偽値で、Python のバイナリをコピーせずにシンボリックの作成を試みるかどうかを示します。

  - `upgrade` -- 真偽値で、真の場合実行中の Python で既存の環境をアップグレードします。その Python がインプレースでアップグレードされたときに用います。デフォルトは `False` です。

  - `with_pip` -- 真偽値で、真の場合仮想環境に pip がインストールされていることを保証します。`--default-pip` オプションで `ensurepip` を使用します。

  - `prompt` -- 仮想環境がアクティベートされたときに使う文字列（デフォルトは `None` のため、仮想環境のディレクトリ名が使われます）。もし特殊な文字列 `"."` が渡された場合、カレントディレクトリのベース名がプロンプトとして用いられます。

  - `upgrade_deps` -- venv のベースのモジュールを PyPI での最新版にアップデートします。

  バージョン 3.4 で変更: `with_pip` 引数が追加されました。

  バージョン 3.6 で追加: `prompt` 引数が追加されました。

  バージョン 3.9 で追加: `upgrade_deps` 引数が追加されました。

  サードパーティーの仮想環境ツールの作成者は、 `EnvBuilder` を継承して使うことができます。

  返される env-builder オブジェクトには `create` というメソッドがあります:

  `create`(env_dir)

    仮想環境を持つことになるターゲットディレクトリ (絶対パスあるいは現在のディレクトリからの相対パス) を指定し、仮想環境を作成します。 `create` メソッドは、指定されたディレクトリに仮想環境を構築するか、適切な例外を送出します。

    `EnvBuilder` クラスの `create` メソッドは、サブクラスのカスタマイズに使えるフックを説明します:

        def create(self, env_dir):
            """
            Create a virtualized Python environment in a directory.
            env_dir is the target directory to create an environment in.
            """
            env_dir = os.path.abspath(env_dir)
            context = self.ensure_directories(env_dir)
            self.create_configuration(context)
            self.setup_python(context)
            self.setup_scripts(context)
            self.post_setup(context)

    メソッド `ensure_directories()`, `create_configuration()`, `setup_python()`, `setup_scripts()`, `post_setup()` はそれぞれオーバーライドできます。

  `ensure_directories`(env_dir)

    仮想環境のディレクトリとすべての必要なサブディレクトリのうちまだ存在しないものを作成し、コンテキストオブジェクトを返します。このコンテキストオブジェクトは他のメソッドで使うために（パスなどの）属性を保持しているだけです。もし `EnvBuilder` が `clear=True` の引数で作成された場合、仮想環境のディレクトリの中身は消去され、すべての必要なサブディレクトリが再作成されます。

    返されるコンテキストオブジェクトは以下の属性を持った `types.SimpleNamespace` です:

    - `env_dir` - 仮想環境の場所。アクティベートスクリプトの中の `__VENV_DIR__` で使われます（`install_scripts()` を参照してください）。

    - `env_name` - 仮想環境の名前。アクティベートスクリプトの中の `__VENV_NAME__` で使われます（`install_scripts()` を参照してください）。

    - `prompt` - アクティベートスクリプトで使われるプロンプト。アクティベートスクリプトの中の `__VENV_PROMPT__` で使われます（`install_scripts()` を参照してください）。

    - `executable` - 仮想環境の元になっている Python 実行可能ファイル。これは仮想環境が別の仮想環境から作られた場合も考慮に入れます。

    - `inc_path` - 仮想環境の include パス。

    - `lib_path` - 仮想環境の purelib パス。

    - `bin_path` - 仮想環境のスクリプトのパス。

    - `bin_name` - 仮想環境の場所に相対的な、スクリプトのパス。アクティベートスクリプトの中の `__VENV_BIN_NAME__` で使われます（`install_scripts()` を参照してください）。

    - `env_exe` - 仮想環境の中の Python インタプリタの名前。アクティベートスクリプトの中の `__VENV_PYTHON__` で使われます（`install_scripts()` を参照してください）。

    - `env_exec_cmd` - ファイルシステムのリダイレクトを考慮に入れた、Python インタプリタの名前。これは仮想環境の中で Python を実行するのに使えます。

    バージョン 3.12 で変更: コンテキストに `lib_path` 属性が追加され、コンテキストオブジェクトがドキュメントに追加されました。

    バージョン 3.11 で変更: venv システム構成インストールスキーム は作成されたディレクトリのパスを構築するために使われます。

  `create_configuration`(context)

    仮想環境に `pyvenv.cfg` 設定ファイルを作成します。

  `setup_python`(context)

    Python 実行ファイルのコピーまたはシンボリックリンクを仮想環境に作成します。 POSIX システムで、特定の `python3.x` 実行ファイルが使われている場合、同じ名前のファイルが既に存在していない限り、 `python` および `python3` へのシンボリックリンクがその実行ファイルを指すように作成されます。

  `setup_scripts`(context)

    プラットフォームに対応した有効化スクリプトを仮想環境にインストールします。

  `upgrade_dependencies`(context)

    仮想環境の中の venv のコア依存関係パッケージ（現在は `pip` と `setuptools`）をアップグレードします。これは仮想環境の中の `pip` 実行可能ファイルによって行われます。

    バージョン 3.9 で追加.

  `post_setup`(context)

    サードパーティーライブラリがオーバーライドするための空のメソッドです。このメソッドをオーバーライドして、仮想環境構築後にパッケージのプリインストールなどのステップを実装できます。

  バージョン 3.7.2 で変更: Windows では、バイナリそのものをコピーするのではなく、`python[w].exe` にリダイレクトを行うスクリプトを使うようになりました。 3.7.2 でのみ、ソース群でビルドを実行しているのでなければ `setup_python()` だけは何もしません。

  バージョン 3.7.3 で変更: Windows では、 `setup_scripts()` の代わりに `setup_python()` の一部としてリダイレクトを行うスクリプトをコピーします。 これは 3.7.2 には当てはまりません。 シンボリックリンクを使ったときは、オリジナルの実行ファイルをコピーします。

  これらに加えて、 `EnvBuilder` は `setup_scripts()` やサブクラスの `post_setup()` が仮想環境にスクリプトをインストールするためのユーティリティーメソッドを提供しています。

  `install_scripts`(context, path)

    path は "common", "posix", "nt" ディレクトリを格納したディレクトリへのパスです。各サブディレクトリには仮想環境の bin ディレクトリにインストールするスクリプトを格納します。 "common" の中身と、 `os.name` に一致するディレクトリの中身を、以下の置換処理を行いながらコピーします:

    - `__VENV_DIR__` は仮想環境ディレクトリの絶対パスに置換されます。

    - `__VENV_NAME__` は仮想環境の名前 (仮想環境ディレクトリのパスの最後の部分) に置換されます。

    - `__VENV_PROMPT__` はプロンプトに置換されます (括弧で囲まれ空白が続く環境名)。

    - `__VENV_BIN_NAME__` は bin ディレクトリ名 (`bin` か `Scripts`) に置換されます。

    - `__VENV_PYTHON__` は仮想環境の Python 実行ファイルの絶対パスに置換されます。

    (既存環境のアップグレード中は) ディレクトリは存在しても構いません。

モジュールレベルの簡易関数もあります:

`venv.``create`(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False)

  `EnvBuilder` を指定されたキーワード引数を使って作成し、その `create()` メソッドに env_dir 引数を渡して実行します。

  バージョン 3.3 で追加.

  バージョン 3.4 で変更: `with_pip` 引数が追加されました。

  バージョン 3.6 で変更: `prompt` 引数が追加されました。

  バージョン 3.9 で変更: `upgrade_deps` 引数が追加されました。

## `EnvBuilder` を拡張する例

次のスクリプトで、作成された仮想環境に setuptools と pip をインストールするサブクラスを実装して `EnvBuilder` を拡張する方法を示します:

    import os
    import os.path
    from subprocess import Popen, PIPE
    import sys
    from threading import Thread
    from urllib.parse import urlparse
    from urllib.request import urlretrieve
    import venv

    class ExtendedEnvBuilder(venv.EnvBuilder):
        """
        This builder installs setuptools and pip so that you can pip or
        easy_install other packages into the created virtual environment.

        :param nodist: If true, setuptools and pip are not installed into the
                       created virtual environment.
        :param nopip: If true, pip is not installed into the created
                      virtual environment.
        :param progress: If setuptools or pip are installed, the progress of the
                         installation can be monitored by passing a progress
                         callable. If specified, it is called with two
                         arguments: a string indicating some progress, and a
                         context indicating where the string is coming from.
                         The context argument can have one of three values:
                         'main', indicating that it is called from virtualize()
                         itself, and 'stdout' and 'stderr', which are obtained
                         by reading lines from the output streams of a subprocess
                         which is used to install the app.

                         If a callable is not specified, default progress
                         information is output to sys.stderr.
        """

        def __init__(self, *args, **kwargs):
            self.nodist = kwargs.pop('nodist', False)
            self.nopip = kwargs.pop('nopip', False)
            self.progress = kwargs.pop('progress', None)
            self.verbose = kwargs.pop('verbose', False)
            super().__init__(*args, **kwargs)

        def post_setup(self, context):
            """
            Set up any packages which need to be pre-installed into the
            virtual environment being created.

            :param context: The information for the virtual environment
                            creation request being processed.
            """
            os.environ['VIRTUAL_ENV'] = context.env_dir
            if not self.nodist:
                self.install_setuptools(context)
            # Can't install pip without setuptools
            if not self.nopip and not self.nodist:
                self.install_pip(context)

        def reader(self, stream, context):
            """
            Read lines from a subprocess' output stream and either pass to a progress
            callable (if specified) or write progress information to sys.stderr.
            """
            progress = self.progress
            while True:
                s = stream.readline()
                if not s:
                    break
                if progress is not None:
                    progress(s, context)
                else:
                    if not self.verbose:
                        sys.stderr.write('.')
                    else:
                        sys.stderr.write(s.decode('utf-8'))
                    sys.stderr.flush()
            stream.close()

        def install_script(self, context, name, url):
            _, _, path, _, _, _ = urlparse(url)
            fn = os.path.split(path)[-1]
            binpath = context.bin_path
            distpath = os.path.join(binpath, fn)
            # Download script into the virtual environment's binaries folder
            urlretrieve(url, distpath)
            progress = self.progress
            if self.verbose:
                term = '\n'
            else:
                term = ''
            if progress is not None:
                progress('Installing %s ...%s' % (name, term), 'main')
            else:
                sys.stderr.write('Installing %s ...%s' % (name, term))
                sys.stderr.flush()
            # Install in the virtual environment
            args = [context.env_exe, fn]
            p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
            t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
            t1.start()
            t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
            t2.start()
            p.wait()
            t1.join()
            t2.join()
            if progress is not None:
                progress('done.', 'main')
            else:
                sys.stderr.write('done.\n')
            # Clean up - no longer needed
            os.unlink(distpath)

        def install_setuptools(self, context):
            """
            Install setuptools in the virtual environment.

            :param context: The information for the virtual environment
                            creation request being processed.
            """
            url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
            self.install_script(context, 'setuptools', url)
            # clear up the setuptools archive which gets downloaded
            pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
            files = filter(pred, os.listdir(context.bin_path))
            for f in files:
                f = os.path.join(context.bin_path, f)
                os.unlink(f)

        def install_pip(self, context):
            """
            Install pip in the virtual environment.

            :param context: The information for the virtual environment
                            creation request being processed.
            """
            url = 'https://bootstrap.pypa.io/get-pip.py'
            self.install_script(context, 'pip', url)

    def main(args=None):
        compatible = True
        if sys.version_info < (3, 3):
            compatible = False
        elif not hasattr(sys, 'base_prefix'):
            compatible = False
        if not compatible:
            raise ValueError('This script is only for use with '
                             'Python 3.3 or later')
        else:
            import argparse

            parser = argparse.ArgumentParser(prog=__name__,
                                             description='Creates virtual Python '
                                                         'environments in one or '
                                                         'more target '
                                                         'directories.')
            parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
                                help='A directory in which to create the '
                                     'virtual environment.')
            parser.add_argument('--no-setuptools', default=False,
                                action='store_true', dest='nodist',
                                help="Don't install setuptools or pip in the "
                                     "virtual environment.")
            parser.add_argument('--no-pip', default=False,
                                action='store_true', dest='nopip',
                                help="Don't install pip in the virtual "
                                     "environment.")
            parser.add_argument('--system-site-packages', default=False,
                                action='store_true', dest='system_site',
                                help='Give the virtual environment access to the '
                                     'system site-packages dir.')
            if os.name == 'nt':
                use_symlinks = False
            else:
                use_symlinks = True
            parser.add_argument('--symlinks', default=use_symlinks,
                                action='store_true', dest='symlinks',
                                help='Try to use symlinks rather than copies, '
                                     'when symlinks are not the default for '
                                     'the platform.')
            parser.add_argument('--clear', default=False, action='store_true',
                                dest='clear', help='Delete the contents of the '
                                                   'virtual environment '
                                                   'directory if it already '
                                                   'exists, before virtual '
                                                   'environment creation.')
            parser.add_argument('--upgrade', default=False, action='store_true',
                                dest='upgrade', help='Upgrade the virtual '
                                                     'environment directory to '
                                                     'use this version of '
                                                     'Python, assuming Python '
                                                     'has been upgraded '
                                                     'in-place.')
            parser.add_argument('--verbose', default=False, action='store_true',
                                dest='verbose', help='Display the output '
                                                   'from the scripts which '
                                                   'install setuptools and pip.')
            options = parser.parse_args(args)
            if options.upgrade and options.clear:
                raise ValueError('you cannot supply --upgrade and --clear together.')
            builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
                                           clear=options.clear,
                                           symlinks=options.symlinks,
                                           upgrade=options.upgrade,
                                           nodist=options.nodist,
                                           nopip=options.nopip,
                                           verbose=options.verbose)
            for d in options.dirs:
                builder.create(d)

    if __name__ == '__main__':
        rc = 1
        try:
            main()
            rc = 0
        except Exception as e:
            print('Error: %s' % e, file=sys.stderr)
        sys.exit(rc)

このスクリプトは オンライン よりダウンロードすることも可能です。