それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

pyenvとpipenvで環境を整える。

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.6pythonのバージョンを指定する、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は動くが、忘れるとあとで手痛い時間浪費をするはめになる。

バージョンつけてなくてデプロイエラーでシェル起動したときにパニクったよ。。。