setup.pyのdependency_linksの書き方
前回の続き
前回の記事でpipコマンドにGithubのリポジトリにsshで接続するURLを指定する方法を紹介した。
今度はsetup.pyで非公開プロジェクトを依存パッケージに指定する方法をここにメモしておく。
なお、わたしはwheelパッケージの仕様を知らないのでここでは旧式のeggパッケージを作ることを想定して話を進める。
依存パッケージをPyPI以外から取得するときはdependency_links
setup.pyのsetup関数にはdependency_linksという引数を渡せる。
これを使って依存パッケージの所在を指定できる。
ところがURLの指定方法に込み入ったルールがあり、pipのときと違って何かと不都合が多く注意を要する。
試しにpython-dateutilをsshのURLで入れてみる
試しにdateutilモジュールをdependency_linksを使って入れてみる。
リポジトリの名前はdateutil、しかしパッケージの名前はpython-dateutil
まず、ダメな例を示す。これだとうまくいかないので注意。
setup(... install_requires=['python-dateutil'], dependency_links=['git+ssh://git@github.com/dateutil/dateutil.git'], ... )
コンソール出力を見ると、
Searching for python-dateutil Reading git+ssh://git@github.com/dateutil/dateutil.git Download error on git+ssh://git@github.com/dateutil/dateutil.git: unknown url type: git+ssh -- Some packages may not be found! Reading https://pypi.python.org/simple/python-dateutil/ Reading http://labix.org/python-dateutil Reading https://dateutil.readthedocs.org Best match: python-dateutil 2.4.0 Downloading https://pypi.python.org/packages/source/p/python-dateutil/python-dateutil-2.4.0.tar.gz#md5=75714163bb96bedd07685cdb2071b8bc
はい、赤字部分の通り、Githubからパッケージを取得しようとして失敗したので結局PyPIから取得している。
原因は、dateutilは正式にはpython-dateutilというパッケージ名で、Githubのリポジトリの名前 "dateutil" と違うから。
#egg=なんちゃら の部分が大事
dependency_linksのURLに#egg=python_dateutilというフラグメント識別子をつけるとこの問題が解決する(以下)。
setup(... install_requires=['python-dateutil'], dependency_links=['git+ssh://git@github.com/dateutil/dateutil.git#egg=python_dateutil'], ... )
install_requiresには "python-dateutil" とハイフン区切りにするが、dependency_linksのゲタは "python_dateutil" とアンダースコア区切りになる。
(後述するが、これには理由がある)
コンソール出力を見ると、
Searching for python-dateutil Best match: python-dateutil [unknown version] Doing git clone from ssh://git@github.com/dateutil/dateutil.git to /tmp/easy_install-1Y4QDO/dateutil.git Processing dateutil.git Writing /tmp/easy_install-1Y4QDO/dateutil.git/setup.cfg Running setup.py -q bdist_egg --dist-dir /tmp/easy_install-1Y4QDO/dateutil.git/egg-dist-tmp-VUkHXx Adding python-dateutil 2.4.0 to easy-install.pth file Installed /home/echizen/foolish/lib/python2.7/site-packages/python_dateutil-2.4.0-py2.7.egg
今度はPyPIに問い合わせに行かなくなり、期待通りの結果となる。
ね、簡単でしょ?
ここまでは簡単。
では、dateutilの2.4.0バージョンを指定してインストールするときはどうだろうか。
バージョンを指定すると??
その場合は以下となる。
setup(... install_requires=['python-dateutil==2.4.0'], dependency_links=['git+ssh://git@github.com/dateutil/dateutil.git@2.4.0#egg=python_dateutil-2.4.0'], ... )
dateutil.gitというリポジトリ名の後ろの部分が複雑になる。
@2.4.0#egg=python_dateutil-2.4.0
ゲタに加えてアットマークまで出てくるので余計混乱する。
アットマークの後ろはGitのブランチやタグの名前を書く
アットマークの後ろはなぬものだ?と。生まれてこの方見だこだぁねぇ、と。
おら東京さ行ぐだと、銀座に山買うだぇと。
アットマークの後ろはGitのブランチやタグの名前である。
https://github.com/dateutil/dateutil/tree/2.4.0
https://github.com/dateutil/dateutil/releases/tag/2.4.0
この通り、python-dateutilプロジェクトには2.4.0というタグが存在する。
もしブランチを指定するなら @master とか @t2015 などと書く。
ゲタの後ろはPythonパッケージの名前とバージョン名をハイフン区切りで書く
次に、ゲタの後ろの部分だが、python_dateutilはパッケージの名前、2.4.0がバージョンの名前となる。
(パッケージ名とバージョン名をハイフンで区切るから、パッケージ名の中の区切り文字はアンダースコアに置き換えられる)
つまり、
git+ssh://git@github.com/dateutil/dateutil.git@2.4.0#egg=python_dateutil-2.4.0
これはpython-dateutilの2.4.0バージョンが欲しければ、そのリポジトリの2.4.0のタグを見に行けばあるよ、と教えているのである。
参考リンク
python-dateutil==2.4.0とか>2.0, <=2.3とか、バージョンを指定する式
https://pythonhosted.org/setuptools/setuptools.html#declaring-dependencies
pipのパッケージURL指定方法(git向け)
https://pip.pypa.io/en/latest/reference/pip_install.html#git