pipのsetuptools離れ

年明けに pip 1.5 がリリースされ、1.4でのpreリリースの扱いに加えて、外部サイトにおいてあるライブラリがインストールできなくなった(allow-externalオプションが必要)り、httpsじゃないサイトからのダウンロードができなくなった(allow-unverified )り、阿鼻叫喚のようです。

そのあたりはエラーメッセージの通りにしてよね!ってことで、そことは別の話です。

pip1.5以降はpkg_resourcesというsetuptoolsに入ってたモジュールをpip内に同梱するようになりました。 1.4のときにdistlibも同梱されるようになっているため、pythonのパッケージングに関するユーティリティライブラリを新旧ともにpipは同梱するようになったわけです。

さらに get-pip はsetuptoolsがなければそれもインストールするようになりました。 って話で終わると、別にsetuptools離れしてないじゃんということになりますが。 get-pipの動作を見ていると、pipをインストールしてから、setuptoolsをインストールしています。 ここで、1.5以降のChangeLogを見てみると、pipはsdistをインストールするとき以外はsetuptoolsを必要としなくなったと書いてあります。 get-pipはpipとsetuptoolsをwheel形式を使ってインストールするので、pipがsetuptoolsをインストールするということが可能になったわけです。 で、pyvenv/ensure-pipやvirtualenvなどは環境作成時にpipもsetuptoolsもインストールするので、setuptoolsなしでpipのみという環境はそうそう存在しないのです。 とはいえ、できるようになったというのなら確認してやろうじゃありませんか。

今のところの最新安定版のpython3.3に入っているpyvenvはensure-pipがないので、まっさらな環境を作成できます。この環境にpipのみの単独インストールをしてみます。

さて、pipをインストールするといってもpipのsetup.pyはsetuptoolsを使っているので、wheelからのインストールを検討しなければなりません。 が、現状でwheelをインストールできるツールはpipだけ。だからこそget-pipがあるわけですが、今回はそれも使わないことにします。

pipがなければdistlibを使えばいいじゃない! pipが内部で利用しているパッケージング関連のライブラリであるdistlibを pypi の distlib からダウンロードしておきます。 また、インストール対象のpipのwheelディストリビューションも pypi の pip からダウンロードしておきます。

この時点で以下のような状態です:

$ ls
bin  distlib-0.1.7.zip  include  lib  pip-1.5.2-py2.py3-none-any.whl  pyvenv.cfg

もちろんsetuptoolsは入っていません:

$ bin/python -m setuptoools
/home/aodag/works/pip-only/bin/python: No module named setuptoools

distlibを解凍して、環境変数PYTHONPATHにdistlib以下のパスを追加します:

$ unzip distlib-0.1.7.zip
$ export PYTHONPATH=$PWD/distlib-0.1.7

では、distlibを使ってpipをインストールします。

distlib.wheel.Wheelクラスを使って、pipのwheelファイルを読み込みます:

>>> from distlib.wheel import Wheel
>>> whl = Wheel('pip-1.5.2-py2.py3-none-any.whl')
>>> whl
<distlib.wheel.Wheel object at 0x7f759e2d3110>
>>> whl.info
{'Wheel-Version': '1.0', 'Generator': 'bdist_wheel (0.22.0)', 'Tag': 'py2-none-any', 'Root-Is-Purelib': 'true'}
>>> whl.metadata.todict()
{'license': 'MIT', 'keywords': 'easy_install distutils setuptools egg virtualenv', 'classifiers': ['Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Topic :: Software Development :: Build Tools', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3'], 'summary': 'A tool for installing and managing Python packages.', 'version': '1.5.2', 'name': 'pip'}

インストール先のパスを用意します:

>>> import site
>>> site_packages = site.getsitepackages()[0]
>>> import sys
>>> import os
>>> paths = dict(prefix="", purelib=site_packages, platlib=site_packages, data="", scripts=os.path.join(sys.prefix, "bin"), headers="")

スクリプトインストールのためにScriptMakerも作成して、installメソッドを呼びます:

>>> from distlib.scripts import ScriptMaker
>>> maker = ScriptMaker(None, None)
>>> whl.install(paths, maker)
<InstalledDistribution 'pip' 1.5.2 at '/home/aodag/works/pip-only/lib/python3.3/site-packages/pip-1.5.2.dist-info'>

これでpipのインストール完了です。

$ pip --version
pip 1.5.2 from /home/aodag/works/pip-only/lib/python3.3/site-packages (python 3.3)

では、この状態でwheel形式で配布されているものをインストールしてみます。 依存ライブラリがsdistだと、そこでsetuptoolsが必要になってしまうので、それほど多くのものはインストールできません。 とりあえず2つ試しました。

$ pip install webdispatch
Downloading/unpacking webdispatch
  Downloading WebDispatch-1.0.1-py2.py3-none-any.whl
Installing collected packages: webdispatch
Successfully installed webdispatch
Cleaning up...
$ pip install pastedeploy
Downloading/unpacking pastedeploy
  Downloading PasteDeploy-1.5.2-py2.py3-none-any.whl
Installing collected packages: pastedeploy
Successfully installed pastedeploy
Cleaning up...

ちゃんとsetuptoolsなしで実行できています。 とはいえ、例えばmakoやsphinxなどは、それ自体はwheelで配布されていますが、依存ライブラリがsdistなので、pipだけでのインストールはできません。 今後wheel形式の配布が広まらなければ、setuptoolsは不滅なのでしょう。

Comments !

blogroll

social