スキップしてメイン コンテンツに移動

pipenvを使う

2019年頃から、Pythonの開発環境としてpipenvが良いなんて話を耳にしていた。
ようやく近頃使う機会があって、確かに使い勝手もよかったので、簡単にまとめておく。

まず、これまでのPythonの環境だと、単純に依存しているモジュールをpipのfreezeコマンドで出力してrequirements.txtに書くやり方にするといくつか問題があった。

・環境を仮想化しないとその端末に入っている全てのライブラリを使用しているライブラリとして書き出してしまうな上、仮想化のやり方が色々とあって面倒
・直接依存しているものと、間接的に依存しているもの(依存しているものが依存しているもの)との区別がつかない
・requirements.txtを慎重に書かないと間接的な依存先のバージョンが変わったことでライブラリが壊れてしまうなどのトラブルや、インストールしたタイミングによってバージョンが異なってしまうことがある

pipenvでは
・プロジェクトごとに環境を仮想化すること
・直接の依存と間接的な依存をがわけて管理されるようになった
・バージョンをロックする機構ができた
ってことでこのあたりのトラブルがかなり解消された。
現行は、セットアップの面倒さに目を瞑れば、JavaScript系の開発と同様の勝手になり、相当スムースになったと個人的には思う。
(JS開発系におけるpackage.json = Pipfile, yarn.lock = Pipfile.lock)


しんどかった点ので対応に苦慮した点を3つほど記しておく。

事前ライブラリインストール
pipenvの中で使うpyenvを適切に準備するために、事前に次のコマンドでライブラリをインストールしていないと、一見セットアップがうまくいくのに動かない、といったトラブルに出会すことになる。(Ubuntu環境前提の話)
そして、この必要なライブラリについて公式ドキュメントでは触れられていないように見える。(見落としかもしれないけれどね)

sudo apt update
sudo apt install python3.7-distutils
sudo apt install zlib1g-dev
sudo apt install libssl-dev libbz2-dev libreadline-dev libsqlite3-dev

WSLで動かす場合のPython指定
それからWSLで動かす場合には次のようにpythonを指定しないと、WSL内からWindowsのpythonをつかんでしまって失敗するという、驚きのエラーにハマることになる。

pipenv --python /PATH/TO/HOME/WITHOUT/VAR/.pyenv/versions/3.7.5/bin/python

cronで動かすときのパス
公式では次のようなコマンドでインストールするようにと記載がある。

pip install pipenv —user

この方法でインストールする場合、cronだと環境にもよるがpipenvへのパスが通らなくなってしまうことがある。
その場合、cronの処理の中のどこかで次のように、pipenvへのパスを通す必要がある。

export PATH="/usr/local/bin:${PATH}"

ここまでで書いた話については基本的に次のリンクを参考に解決した。

Pipenv & Virtual Environments — pipenv 2018.11.27.dev0 documentation https://pipenv-fork.readthedocs.io/en/latest/install.html#installing-pipenv
WSLのpipenvでpython3.7を使う - えむにわリソースhttps://m2wasabi.hatenablog.com/entry/2019/10/22/193150

ここまでで書いたあたりを適切に対処すれば、pipenvはとても使いやすいと思う。
setup.pyとsetup.cfgを用意した前提で次のコマンドも実行すればパスが通るのでIDEでの補完も効くようになるのにもとても気に入った。

pipenv install -e .

Pipfile自体は初回セットアップ時に生成される。
setup.pyは次のようにシンプルでOK。

from setuptools import setup
setup()

またsetup.cfgは次の内容だけ書いた。toml形式。

[metadata]
name = name_of_your_tool
version = ‘1.0.0
description = This is sample description
[scripts]
start = "python src/main.py"

setup.pyの記載がスーパーシンプルなのは、どこかの記載でこれでOKだと呼んだからなのだけど(あなたが作っているのはアプリかライブラリか、アプリなら……といった場合わけなどと一緒に書かれていた)、いずれにせよ、この状態で開発を複数人で進めていてこの数週間トラブルは起きていない。

setup.pyとsetup.cfgについては次のリンクを参考にした。

Structuring Your Project — The Hitchhiker's Guide to Python https://docs.python-guide.org/writing/structure/
GitHub - dropbox/merou: Permission management service https://github.com/dropbox/merou

mypyやflake8をプロジェクトで使用しているので、上記に加えてmerouにあったsetup.cfgを参考に実際のsetup.cfgには書き足している。