pipenv 環境を作る
素の状態でpipenvをインストールしていきます。
適当に仮想マシン(コンテナ)を用意します。仮想マシンにログインします。
lxc launch ubuntu:20.04 pyenv-test lxc exec pyenv-test -- adduser takuya lxc exec pyenv-test -- usermod -aG sudo takuya lxc exec pyenv-test -- sudo --login --user takuya
必要なものをインストールします。
sudo apt update; sudo apt -y install make build-essential libssl-dev zlib1g-dev \ libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \ libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
ubuntu なので git などが最初から入ってます。debian の場合 git は自分でいれる必要があるかもしれない。
pip もあったほうが楽なので持ってきてもいいですが、ややこしくなるので後で入れよう。
## あとで(後述) sudo apt install python3-pip
pyenvの環境を整える
最初に、python3 の各種バージョンを整えておきます。
pyenv を持ってきます。
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
pyenv をコマンドにPATH通します。
export PYENV_ROOT=$HOME/.pyenv export PATH=$PYENV_ROOT/bin:$PATH eval "$(pyenv init -)"
永続化が必要なときは、.bashrc にでも書けばおっけ
インストールが可能なバージョンを調べます。
pyenv install -l
いくつかのバージョンを入れて動作確認をしてみます。 CPython 3.9.6 を入れます。
[[ $(pyenv versions) =~ 3.9.6 ]] || pyenv install 3.9.6
CPython 3.9.7 を入れます。
[[ $(pyenv versions) =~ 3.9.7 ]] || pyenv install 3.9.7
ここまでで、pyenv 環境を作れました。
pipenv環境を作ります。
pipenv は、プロジェクトフォルダ内部に作ったほうが管理がわかりやすくて好きなので、プロジェクトファイル内に作ります。
pipコマンドについては、pyenv でインストールされている。pyenv由来を使うか、OS由来を使うかはその後のバージョン利用次第かな。
system/pipあり(apt install python3-pipを入れていた場合)
後述
pipなし(apt install python3-pipをしてないとき)
mkdir myProjcet cd myProjcet pyenv local 3.9.6 pyenv exec pip install pipenv PIPENV_VENV_IN_PROJECT=1 pyenv exec pipenv install --python=3.9.6
system / pip について
OS由来のpip コマンドを使うか使わないかで、あとあとトラブル(大抵の場合は、pyenv コマンド選択ミス)になるので、わたしは入れずに済むときは system pip を入れてない。
コマンドについて
PIPENV_VENV_IN_PROJECT=1 pipenv install --python=3.9.6
PIPENV_VENV_IN_PROJECT
を指定すると、現在のフォルダ内部に.venv作成します。
デフォルトは~/.venv
となり、$HOMEにある。pyenv/pipenv視点からは管理はしやすい。
プロジェクトフォルダがいっぱいあるときは、増えすぎて何が何だか分からなくなった。
それ以来はプロジェクト内部に作ることしている。npm/yarn/composer なんかはプロジェクト内部だしね。
オプションのバージョン指定につて。
pipenv install --python=3.9.6
のところは、pipenv install
でpipenvを作成する。
--python=3.9.6
でpythonのバージョンを指定する、pyenvでインストールしたものをAliasで持ってきます。
バージョンはpyenv versions
で出てくるものが利用可能で、pyenv local 3.9.6
で指定してあれば、.python-version
に従う。
pip のありなしは、pipコマンドを叩けばわかる。
$pip install pipenv Command 'pip' not found, but can be installed with: sudo apt install python3-pip
インストール完了の確認
なにもしないプロジェクトの場合、次のようにファイルが作られる。
takuya@pyenv-test:~/myProjcet$ ls -alt total 7 drwxrwxr-x 3 takuya takuya 6 Feb 10 15:59 . -rw-r--r-- 1 takuya takuya 453 Feb 10 15:59 Pipfile.lock -rw-rw-r-- 1 takuya takuya 138 Feb 10 15:59 Pipfile drwxrwxr-x 4 takuya takuya 7 Feb 10 15:59 .venv drwxr-xr-x 6 takuya takuya 11 Feb 10 15:59 .. -rw-rw-r-- 1 takuya takuya 6 Feb 10 15:56 .python-version
.venv
にpipパッケージが入る。
pipenv の利用
このあとpipenv を使っていく
pipenv shell
または
pyenv exec pipenv shell
shell を指定することで、pyenv 環境下に作ったpipenv が有効になる
pipenv shell をした場合
pipenv shell で実行すると、次のように、シェルの前にvenv の名前が付与される。
takuya@pyenv-test:~/myProjcet$ pyenv exec pipenv shell Launching subshell in virtual environment... takuya@pyenv-test:~/myProjcet$ . /home/takuya/myProjcet/.venv/bin/activate (myProjcet) takuya@pyenv-test:~/myProjcet$
pipenv 環境下でインストールする
(myProjcet) takuya@pyenv-test:~/myProjcet$ pip install speedtest-cli
pipenv 環境下でpip由来コマンドを実行する
インストールした speedtest パッケージを早速使ってみる。
インストール後にコマンド・ファイルが作成されたパス(場所)を確認
(myProjcet) takuya@pyenv-test:~/myProjcet$ which speedtest /home/takuya/myProjcet/.venv/bin/speedtest
実行してみる。
(myProjcet) takuya@pyenv-test:~/myProjcet$ speedtest Retrieving speedtest.net configuration... Testing from Softbank BB (xxxxxx)... Retrieving speedtest.net server list... Selecting best server based on ping... Hosted by BudgetVM (Tokyo) [423.63 km]: 18.959 ms Testing download speed.............................................
pipenv 内部にいるので、$PATHが解決されてて、コマンドが直接利用可がわかる。
shell 以外の実行法
pipenv shell
を使わなくても使えます。
pyenv exec pipenv run pip install mycli pyenv exec pipenv run mycli
exec や run が冗長ですが、pyenv と pipenv とコマンドの関係がわかりやすのではないでしょうか
system pip がある場合
システムにpipを入れた場合
sudo apt install python3-pip
pipコマンドはユーザー空間 ~/.local/ に pipを作ります。
pip install --upgrade pip export PATH=$PATH:/home/takuya/.local/bin pip install pipenv
pipenv を pyenv の3.9.6で初期化します。
mkdir myProjcet cd myProjcet pyenv local 3.9.6 PIPENV_VENV_IN_PROJECT=1 pipenv install --python=3.9.6
$pyenv local 3.9.6
をつけなくても、pipenvでカバーされます。
pipenvで--python
をつけたのでpyenv local 3.9.6
は省略しても3.9.6の.venvが作られます。
ただし、自動生成(CI/CD)しているときは、後でわからなくなるので、両方つけたほうが無難です。
インストール後の状態
.venv はありますが、.python-versionはありません。.python-versionがないですが、.venv はsystemではありません。
takuya@pyenv-test:~/myProjcet$ ls -alt total 6 drwxrwxr-x 3 takuya takuya 5 Feb 10 16:18 . -rw-r--r-- 1 takuya takuya 453 Feb 10 16:18 Pipfile.lock -rw-rw-r-- 1 takuya takuya 138 Feb 10 16:18 Pipfile drwxrwxr-x 4 takuya takuya 7 Feb 10 16:18 .venv drwxr-xr-x 6 takuya takuya 13 Feb 10 16:16 ..
しかし、python は system のママなので、.venv は 3.9.8 で pythonコマンドは 3.8.4という状況が出来上がります。
.venvのバージョンと pyenvのversionとコマンド位置を見てみる。
takuya@pyenv-test:~/myProjcet$ pyenv version system (set by /home/takuya/.pyenv/version) takuya@pyenv-test:~/myProjcet$ python3 -V Python 3.8.10 takuya@pyenv-test:~/myProjcet$ cat Pipfile [[source]] (略 [requires] python_version = "3.9"
コマンドが複数できちゃった。
別にこのままでも殆どの場合問題なく動くのですが、pip install しているうちにぐちゃぐちゃになって、気づかないうちに、system でプロジェクトを作ってたりして、あれどっちだっけ?って自分でもパニックになることがあったので python-pipを意図的に外して使ったりしています。
ありがちなミスの例
takuya@pyenv-test:~/myProjcet$ pip install speedtest-cli takuya@pyenv-test:~/myProjcet$ pipenv pip install speedtest-cli
うっかりミスで pipenvをすっ飛ばしてvenv環境に入るのを忘れたために・・・
takuya@pyenv-test:~/myProjcet$ which speedtest /home/takuya/.local/bin/speedtest takuya@pyenv-test:~/myProjcet$ pipenv run which speedtest /home/takuya/myProjcet/.venv/bin/speedtest
同じコマンドが複数できちゃって、自分でもどっちを使ってたかわからなくなって、バージョン関連のエラーが出たときに地獄を見たのでした。
もちろん、pyenvもありますから
takuya@pyenv-test:~/myProjcet$ pipenv run which python3 /home/takuya/myProjcet/.venv/bin/python3 takuya@pyenv-test:~/myProjcet$ which python3 /usr/bin/python3
そして、pipenv/venvもありましたから。
takuya@pyenv-test:~/myProjcet$ pipenv run python3 -V Python 3.9.6 takuya@pyenv-test:~/myProjcet$ python3 -V Python 3.8.10 takuya@pyenv-test:~/myProjcet$ pyenv exec python3 -V Python 3.8.10 takuya@pyenv-test:~/myProjcet$
ぼーっとしてるとミスが連鎖してしました。
pythonバージョンを使い分けるとき pyenv local はなくてもpipenvは動くが、忘れるとあとで手痛い時間浪費をするはめになる。
バージョンつけてなくてデプロイエラーでシェル起動したときにパニクったよ。。。