3行で
-
pipenv
はデフォルトで 2階層上のディレクトリまで再帰的にPipfile
を検索し、存在すればそれを参照してしまう - 環境変数
PIPENV_NO_INHERIT
を設定すると、カレントディレクトリのPipfile
だけ参照できる - 環境変数
PIPENV_MAX_DEPTH
で、再帰的に検索する階層の数を指定できる
(デフォルトは3
で、2階層上まで検索する)
問題
Python の環境構築に pipenv
を導入し、試しにいくつかコマンドを実行して使い方を確認していた。
その後、プロジェクト用のディレクトリを作成して pipenv install
を実行すると、親ディレクトリにある Pipfile
を参照してしまい、新たに仮想環境が構築されなかった。
再現させてみる
環境構築を試す。
[dtsu@localhost somedir]$ pipenv --python 3
Creating a virtualenv for this project…
Pipfile: /home/dtsu/somedir/Pipfile
Using /usr/bin/python3.6m (3.6.8) to create virtualenv…
#----- 中略 -----
✔ Successfully created virtual environment!
Virtualenv location: /home/dtsu/.local/share/virtualenvs/somedir-TX9DoPtR
Creating a Pipfile for this project…
プロジェクト用のディレクトリ foo
を作成し、仮想環境を構築しようとする。
[dtsu@localhost somedir]$ mkdir foo
[dtsu@localhost somedir]$ cd foo/
[dtsu@localhost foo]$ pipenv --python 3
Virtualenv already exists!
Removing existing virtualenv…
Creating a virtualenv for this project…
Pipfile: /home/dtsu/somedir/Pipfile
Using /usr/bin/python3.6m (3.6.8) to create virtualenv…
#----- 中略 -----
✔ Successfully created virtual environment!
Virtualenv location: /home/dtsu/.local/share/virtualenvs/somedir-TX9DoPtR
foo
ディレクトリに環境を構築したいのに、先ほど環境構築を試していた somedir
ディレクトリの Pipfile
が参照されている。
原因
pipenv
はデフォルトでは カレントディレクトリ と 2階層上のディレクトリ まで Pipfile
を検索する。
存在すれば、その Pipfile
を使う。
今回は、動作確認したディレクトリの Pipfile
を参照してしまっていたということ。
参考
環境変数 PIPENV_PIPFILE の説明に該当の内容が記載されていた。(気づきにくい。。。)
If set, this specifies a custom Pipfile location.
When running pipenv from a location other than the same directory where the Pipfile is located, instruct pipenv to find the Pipfile in the location specified by this environment variable.
Default is to find Pipfile automatically in the current and parent directories. See also PIPENV_MAX_DEPTH.
PIPENV_MAX_DEPTH
のデフォルト値は 3 であり、カレントディレクトリ → 1階層上のディレクトリ → 2階層上のディレクトリ の順で Pipfile
を検索する。イメージは以下の通り。
# ★ のディレクトリで pipenv install を実行するとする
# 以下の状況では、foo ディレクトリの Pipfile を参照する
somedir
├ Pipfile
└ foo
├ Pipfile
└ bar ★
└ main.py
# 以下の状況では、somedir ディレクトリの Pipfile を参照する
somedir
├ Pipfile
└ foo
└ bar ★
└ main.py
# 以下の状況では、baz ディレクトリに新たに Pipfile が作成される
somedir
├ Pipfile
└ foo
└ bar
└ baz ★
└ main.py
なお、親ディレクトリを参照させたくない場合は 環境変数 PIPENV_NO_INHERIT に適当な値を設定する。
export PIPENV_NO_INHERIT=False
としても、設定は有効になるため注意。
pipenv version 2020.6.2 の以下のコードを見ると、環境変数が存在するだけで有効になることが分かる。
https://github.com/pypa/pipenv/blob/a44b9828bd9a4b780bd0404fa133e544da576436/pipenv/environments.py#L194
PIPENV_MAX_DEPTH = 2
はおそらくバグ回避用。
PIPENV_NO_INHERIT = "PIPENV_NO_INHERIT" in os.environ
"""Tell Pipenv not to inherit parent directories.
This is useful for deployment to avoid using the wrong current directory.
Overwrites ``PIPENV_MAX_DEPTH``.
"""
if PIPENV_NO_INHERIT:
PIPENV_MAX_DEPTH = 2
補足
既に、カレントディレクトリにPipfileが作成されない という記事が存在した。。。
自分用メモのために記事を残しておくこととする。。