LoginSignup
8
5

More than 5 years have passed since last update.

pipenvでPIPENV_PIPFILE環境変数を指定する場合は絶対パスにする

Posted at

Pipenvとは

Pythonのパッケージ管理ツール(Rubyでいうところのbundlerのようなもの)としてpipenvが標準的になってきている。
https://pipenv-ja.readthedocs.io/ja/translate-ja/

Pipfileで必要なパッケージを指定し、pipenv installするとパッケージがインストールされた仮想環境が構築され、以後pipenv shellを実行するとその仮想環境上のshellで作業することができる。
また特定のコマンドを実行したい場合は、pipenv run [実行したいコマンド]とすれば実行できる。

Pipfileのパスを指定する

さて、デフォルトでは実行時のカレントディレクトリにある"Pipfile"という名前のファイルを参照して仮想環境を構築する。
しかし、バッチ処理などをしたい場合に任意のディレクトリからアプリケーションを実行したい。つまりカレントではない場所にあるPipfileを指定して処理を行いたい。

カレントディレクトリにはないPipfileを使うには環境変数PIPENV_PIPFILEでパスを指定すればよい。

export PIPENV_PIPFILE=/path/to/Pipfile
pipenv run python my_script.py

こうすれば事前にこのパスでインストールした仮想環境を使ってpython my_script.pyを実行することができる。

PIPENV_PIPFILEに相対パスを使うとバグる

ただし、相対パスを使うとバグる場合がある。例えば以下のようなシェルスクリプトを使って起動することを考える。

run.sh
script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)               # 実行中のシェルスクリプトがあるパスを取得
export PIPENV_PIPFILE=$script_dir/../Pipfile                      # そのシェルスクリプトの親ディレクトリにあるPipfileを参照
pipenv run python $script_dir/my_script.py                        # pythonを起動

するとpythonを実行しようとしても必要なモジュールがないというエラーが出ることになる。

なぜか?
こちらのページにヒントがあった。以下、引用する。
pipenvで任意のディレクトリからアプリケーションを実行したい

"こうなるのは仮想環境が(カレントディレクトリに対してではなく)Pipfileのパスに対して作られるためのようです。残念ながら、この振る舞いについて明記されたドキュメントは見つけられませんでした。以下にソースコードの該当箇所を抜粋します。"

project.py
    @property
    def name(self):
        if self._name is None:
            self._name = self.pipfile_location.split(os.sep)[-2]
        return self._name

となっている。ここでpipfile_locationにはPIPENV_PIPFILEで指定したファイルパスが入っていると思われる。
先ほどはパスを相対パスで指定してしまったので、self.name = ".." となってしまったものと思われる。

解決法

よって先ほどの挙動を修正するにはシェルスクリプトを以下のように書き換える必要がある。

run.sh
script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
PIPFILE=$script_dir/../Pipfile
export PIPENV_PIPFILE=$(cd $(dirname $PIPFILE) && pwd)/$(basename $PIPFILE)    # 正規化された絶対パスにする
pipenv run python $script_dir/my_script.py
8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5