[Python] setup.py に dependency_links を書いても "Could not find a version that satisfies the requirement" が出る場合の対処方法4種
Python で pip install
可能なパッケージを作成した際、
PyPI に登録してしまえば pip
が適切に処理してくれるので簡単です。
しかし、内部用のライブラリの場合は明示的にリポジトリの場所を指定しなければなりません。
そのための機能として、setuptools.setup()
には dependency_links
という引数があります。
ところが、pip install
しようとした場合、dependency_links
は無視されてしまい、うまくいきません。
dependency_links
は、基本的に python setup.py install
の場合を想定しているようです。
ただ、pip
は setup.py
の上位ラッパー1のはず。
対処方法が無いはずはないと思って調べてみました。
普通に pip install
するとエラーが発生する
まずはエラーが発生する状況を説明します。
例として、インハウスレポジトリ myserver.com
に登録してある mytestlib
というパッケージを想定します。
この時、mytestlib
を使用するアプリケーション(mytestapp)の setup.py
は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # -*- coding: utf-8 -*- import setuptools with open ( 'README.md' ) as f: readme = f.read() with open ( 'LICENSE' ) as f: license = f.read() setuptools.setup( name = 'mytestapp' , version = '0.1' , description = 'Test Application for checking dependency_links' , long_description = readme, url = '', licence = license, packages = setuptools.find_packages(exclude = ( 'tests' , 'docs' )), dependency_links = [ ], install_requires = [ 'mytestlib==0.1' ], test_suite = 'tests' , entry_points = { 'console_scripts' : [ 'mytestapp=mytestapp.main:main' ] } ) |
これを以下のように pip
を使ってインストールしようとすると、"Could not find a version that satisfies the requirement mytestlib==0.1" とエラーが発生してしまいます。
$ pip install git+ssh://git@myserver.com/kokufu/mytestapp.git Collecting git+ssh://git@myserver.com/kokufu/mytestapp.git Cloning ssh://git@myserver.com/kokufu/mytestapp.git to /tmp/pip-req-build-yxzmlrqy Collecting mytestlib==0.1 (from mytestapp==0.1) Could not find a version that satisfies the requirement mytestlib==0.1 (from mytestapp==0.1) (from versions: ) No matching distribution found for mytestlib==0.1 (from mytestapp==0.1) |
解決法1 --process-dependency-links
を使う
pip install
に --process-dependency-links
をつけると以下のようにインストール可能です。
$ pip install --process-dependency-links git+ssh://git@myserver.com/kokufu/mytestapp.git Collecting git+ssh://git@myserver.com/koufu/mytestapp.git Cloning ssh://git@myserver.com/kokufu/mytestapp.git to /tmp/pip-req-build-1k5_70ia DEPRECATION: Dependency Links processing has been deprecated and will be removed in a future release. Collecting mytestlib==0.1 (from mytestapp==0.1) Cloning https://myserver.com/kokufu/mytestlib.git to /tmp/pip-install-vnodyi4t/mytestlib DEPRECATION: Dependency Links processing has been deprecated and will be removed in a future release. ...略 Successfully installed mytestapp-0.1 mytestlib-0.1 |
ただ、よく見てみると DEPRECATION: Dependency Links processing has been deprecated and will be removed in a future release.
との警告が。
--process-dependency-links
は将来的には無くなる可能性があるわけです。
この DEPRECATION、有効な代替手段が無いようで、DEPRECATION 自体を取りやめるべきだという議論も起きています。
参考
現時点では確実なことは言えませんが、DEPRECATION が取りやめになるか、他に有効な代替手段が提供されるのではないかと思います。
解決法2 --find-links
を使う
多分、--process-dependency-links
の正統な代替手段なのだと思われます2。
以下のように、pip
の実行時に信頼できるパッケージを列挙します。
この時、setup.py
内の dependency_links
は無くてもかまいません。
$ pip install --find-links="git+https://myserver.com/kokufu/mytestlib.git#egg=mytestlib-0.1" git+ssh://git@myserver.com/kokufu/mytestapp.git ...略 Successfully installed mytestapp-0.1 mytestlib-0.1 |
参考
この方法、確かに動作するのですが、依存パッケージの数が増えてくると手間がかかりすぎてしまいます3。
また、mytestlib
パッケージの中でさらに dependency_links
が書かれている場合、それも --find-links
で指定しなければなりません。
依存関係が複雑になってきた場合、これは現実的とは言えません。
解決法3 setup.py install
を使う
以下のように一度 clone
してから、python setup.py install
すると dependency_links
が適切に処理されます。
$ git clone ssh://git@myserver.com/kokufu/mytestapp.git $ cd mytestapp $ python setup.py install ...略 Finished processing dependencies for mytestapp==0.1 |
しかし、この方法、せっかく登場した pip
の恩恵が受けられません。特に mytestlib
パッケージの中でさらに dependency_links
が書かれている場合はそれが適切に処理されません。
これは、--find-links
と同様の問題です。
参考
virtualenv - Difference between 'python setup.py install' and 'pip install' - Stack Overflow
解決法4 --requirement
を使う
この方法は解決法とは言えないのですが、一応書いておきます。
まず、以下のような requirements.txt
を用意します。
1 2 | -e git+https://myserver.com/kokufu/mytestlib.git#egg=mytestlib -e git+https://myserver.com/kokufu/mytestapp.git#egg=mytestapp |
pip --requirement
に先の requirements.txt
を指定すればインストール可能です。
1 2 3 | $ pip install --requirement requirements.txt ...略 Successfully installed mytestapp mytestlib |
この --requirement
、そもそも特定の環境をフリーズして別の場所で再現させることを目的とした機能なので、このように使うのが適切とは思えません。
さらに、この方法も mytestlib
パッケージがさらに内部ライブラリに依存している場合、それらを自分で requirements.txt
に列挙しなければなりません4。
結局、どの方法を使うべきか
上記4つの方法の中で、多段の依存関係を適切に処理できるのは「解決法1 --process-dependency-links
を使う」だけです。
そのため、現時点では --process-dependency-links
を使っておくのが良いだろうと思います。
DEPRECATION の警告が出るのが気になるところですが、議論の様子からすると、他に有効な代替手段が出てこない限り削除されることは無いのではないでしょうか。
しばらくは、--process-dependency-links
を使いながら、議論の行方を注意深く見守るのが良いのだろうと思います5。
0 件のコメント:
コメントを投稿