LoginSignup
16
14

More than 3 years have passed since last update.

setup.pyからPipenvに移行するときの便利/迷いポイント

Last updated at Posted at 2018-07-07

はじめに

pypiに登録しない場合でもsetup.pyでパッケージ管理をするのはそれなりにポピュラーなやり方だと思いますが
そこからPipenvに移行して便利な点と少し迷った点について書きました。
以下で挙げている迷いポイントは全て考慮されていていわゆるバッドノウハウ的なものは必要ありません。

便利ポイント

  • constraints.txtを管理しなくてよい
  • dependencies的なものとdevDependencies的なものの扱いが分かれている
  • Dockerfileに書くときの方法も用意されている

迷いポイント

  • 環境がどこにできるのか迷う
  • setup.pyと役割が被っているがsetup.pyを無くせるのか迷う

constraints.txtを管理しなくて良い

そもそもsetup.pyには以下のような決まりがありました。

ライブラリは、 setup.py の install_requires で 抽象的な依存関係 を定義します。 厳密にどのバージョンをインストールし、どこから依存パッケージを取得するかの判断は、あなたが決めることではありません!

とするとsetup.pyだけだと「実際に実行できるか」を担保できないという問題があって
constraints.txtは開発時にバージョンだけを参照するためのものとして使用されていました。

$ pip install -e . -c constraints.txt

つまりこのコマンドは

  • 何をインストールするかは./setup.pyに聞く
  • どのバージョンをインストールするかは./constraints.txtに聞く

という意味で使われていました。

中身はただのpip freezeなので何かライブラリを入れたときに出力しなおす必要があって大分煩わしい感じがあったんですがPipenvなら
$ pipenv install pyyaml
で新しいパッケージを入れたときにPipenv.lockで自動でやってくれます。

dependencies的なものとdevDependencies的なものの扱いが分かれている

個人的にはsetup.pyのextras_requireでテスト用の依存関係はこっちに入れるみたいな運用をしていましたが、
$ pipenv install pyyaml
$ pipenv install --dev pyyaml
のようにするとpackage.jsondependenciesdevDependenciesみたいな感じで分けることができるようになっています。
テスト用のツールやlinter(tox, flake8, mypyとか)は--devで入れるとよいと思います。

Dockerfileに書く時に良い方法も用意されている

単純なPythonアプリの場合はこんな感じになると思います。

FROM python:3.7
WORKDIR /app
COPY app .
RUN pip install pipenv
RUN pipenv install --system --deploy

--system: 仮想環境を作らずにローカルにインストールする。
--deploy: PipfilePipfile.lockに齟齬があった時に自動で更新してくれる便利機能があるが、本番用にビルドする時には余計なので齟齬があったらコケてくれる。
これでいい感じにインストールしてくれると思います。

迷いポイント

環境がどこにできるのか迷う

実際のところPipenvというツール的にはどこにできてもあまり関係ないように作られているのですが
個人的にはVSCodeで補完用のインタプリタを指定するときにどこにあるかわからないと困ったりします。
そういうときは環境変数を
$ export PIPENV_VENV_IN_PROJECT=true
とセットすると今いる場所に.venvディレクトリの中に作ってくれます。
また、環境は作ったり消したりしたくなると思いますが、消すときは
$ pipenv --rm で消せます。

setup.pyと役割が被っているがsetup.pyを無くせるのか迷う

ここに色々書いてありますが...。
要するにpipenvは依存しているライブラリとそのバージョンを管理するものであって

  • pypiに登録するためのメタデータ(バージョン情報とか)が含まれた生成物を作る機能
  • 他のリポジトリからライブラリとして呼び出されるための機能
  • entory_pointsなどを定義する機能

みたいなライブラリとしてのメタ情報を定義する機能は持ちません。
なのでこれらの機能を使わないのであればPipenvだけで良いですし、使うのであればsetup.pyも必要になります。
またPipenvはsetup.pyを使う場合も便利で
$ pipenv install -e . のようにするとsetup.pyの中に書いている依存関係もPipenv, Pipenv.lockによって管理してくれるので
開発環境を新たに作るときには
$ pipenv install --dev
で再現性のある実行環境を作ることができます。

まとめ

setup.pyを開発環境の定義にまで使うのはそれをテストで使用するtoxと併せて良いアイデアだなとは思いつつも
本来は外部からの見え方を定義するものであるはずなので若干の違和感はありました。
Pipenvは完全に開発環境と実行環境のツールとしての位置付けで、とても品質の高いものだと思います。

16
14
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
16
14