パッケージングを支える技術 pyconjp2016

58
2016 9 21 パッケージングを支える技術 PyCon JP 2016 Atsushi Odagiri

Upload: atsushi-odagiri

Post on 13-Apr-2017

907 views

Category:

Software


4 download

TRANSCRIPT

2016年9月21日

パッケージングを支える技術

PyCon JP 2016

Atsushi Odagiri

1 お前だれよ

• 小田切篤

• Beproud, Inc.

2 これまでのお話

• 2013 パッケージングの今と未来• 2014 パッケージングの今• 2015 Packaging最前線

3 アジェンダ

• パッケージングを支えるツール

• ソースパッケージ

• バイナリパッケージ

• パッケージングを支える技術に支えられてみ

よう

4 パッケージングを支える

ツール

• PyPA ってなに?

4.1 PyPA• Python Packaging Authority• パッケージングツールをメンテするグループ

• github.com/pypa• bitbucket.org/pypa

4.2 PyPAの基本ツール• setuptools• virtualenv• pip• wheel

4.3 setuptools• 配布物を作成する

• setup.pyで使われる• easy_install使うのはもうやめましょう• distributeも、いい加減忘れてください• egg? あれは幻です

4.4 今日のsetuptools• 27.2.0• 去年(2016/9/6)18.3

4.5 virtualenv• python環境を仮想化する• プロジェクトごとに使うライブラリを隔離

• python3.3以降では同等の機能がpython本体から提供されている(pyvenv)

4.6 pip• インストーラ

• sdistとwheelを取り扱える• requirements.txt でライブラリを構成管理する

4.7 wheel• wheel形式パッケージを作成するツール• setuptools に bdist_wheel サブコマンドを追加する

4.8 ツールの導入方法

• python3.4以降ではpip,setuptoolsを導入するensurepipが入っているのでpythonインストール後にpipを利用可能

• virtualenvは環境作成時にpip,setuptools,wheelを導入する

• pyvenvはバージョンによって作成後のツール導入が異なる

– 3.3 なし– 3.4以降 ensurepipでpip,setuptoolsが導入される

• どの環境でもget-pip.py でpip,setuptools,wheelを最新にできる

4.9 例えばubuntuのpyvenv• 14.04 の python3.4 は ensurepipが消されているため、–without-pipをつけないとエラーになる

• 16.04 の python3.5はensurepipがpkg_resources-0.0.0という謎のパッケージメタデータを作成する

– そのままpip freezeしたrequirements.txtを作ると他の環境でエラーになる

• 回避策は –without-pip で環境を作ってからget-pip.py でツールを導入する

5 python標準の仕組み• pypaツールはどのようにパッケージをインストールしてpythonインタプリタに認識させるのか?

5.1 PYTHONPATHとsys.path• 環境変数PYTHON_PATHで複数のディレクトリを指定できる

• 指定した内容は ‘sys.path‘ に入る• モジュールやパッケージを ‘import‘ するときは ‘sys.path‘ のディレクトリを探しに行く

• よくわからないところにインストールしても

sys.path に追加できればよい

5.2 site-packages/user-site-packages• サードパーティ製ライブラリの標準インストー

ル先

• debianではさらに dist-packages という謎のディレクトリが存在する

• user-site-packages はユーザー権限でインストールできる

• user-site-packages にインストールするにはpipで ‘–user‘ オプションを使う

5.3 .pth• site-packages などに配置されるファイル• 中にファイルパスを羅列しておくと、インタプ

リタ起動時にすべて ‘sys.path‘ に追加される• ‘./‘ 以外で始まる行があるとpythonコードとして実行されるという謎仕様

• easy_install が活用していた

5.4 distutils• setup.py で使う setup 関数の大元• setuptoolsはdistutilsの拡張• 直接使うことはもうないはず

• 昔はこれで setup.py install などとしていた

6 バイナリディストリビュー

ション wheel• wheelもう使ってるよね?

6.1 PEP 427 – The Wheel BinaryPackage Format 1.0

• バイナリ形式の配布フォーマット

• 既に利用されている

• C拡張を含まない場合はpy2.py3で共通の配布物

6.2 PEP 513 – A Platform Tag forPortable Linux Built Distributions

• これまではLinux向けwheelはpypiにあげられなかった

• manylinux1• linux向けのwheelを作るために決められた

6.3 Linux向けwheelパッケージのつらいところ

• どのようなライブラリがあると想定してよ

いか?

• 依存するライブラリのABIが合わないなどのトラブル

• 依存ライブラリ同梱のためのハックがsetup.pyに散らばる

6.4 Python の ABI• pymalloc• ucs-4• python3ではすべてucs-4ビルド

6.5 wheelの名前規約からわかること• numpy-1.11.2rc1-

cp35-cp35m-manylinux1_x86_64.whl– numpy という名前のパッケージ– 1.11.2rc1 というバージョン– CPython 3.5 のAPI– CPython pymallocビルドのABI– manylinux1_x86_64 プラットフォーム

6.6 manylinux1が想定するLinux環境• Centos5.11相当• x86とx86_64の両方• その他前提としてよいライブラリ

6.7 manylinux1でインストールを期待してよいライブラリ(1)

• libpanelw.so.5• libncursesw.so.5• libgcc_s.so.1• libstdc++.so.6• libm.so.6• libdl.so.2• librt.so.1• libcrypt.so.1• libc.so.6

• libnsl.so.1

6.8 manylinux1でインストールを期待してよいライブラリ(2)

• libutil.so.1• libpthread.so.0• libX11.so.6• libXext.so.6• libXrender.so.1• libICE.so.6• libSM.so.6• libGL.so.1• libgobject-2.0.so.0

• libgthread-2.0.so.0• libglib-2.0.so.0

6.9 auditwheel• linux向けwheelをmanylinux1に変換するツール

• manylinux1を満たしているかチェック• 依存ライブラリをwheelに同梱させる• wheelファイル名のplatform tagをmanylinux1に変更

6.10 dockerを利用してパッケージを作成する

• docker イメージが用意されている– quay.io/reposi-

tory/pypa/manylinux1_x86_64• CIでこのイメージを利用してパッケージングする

– werckerやgitlabでは直接dockerイメージを利用できる

– travisなどでもCIのワークフロー中にdockerイメージを利用できる

6.11 werckerでやってみようbox:

id: quay.io/pypa/manylinux1_x86_64registry: quay.io

build:steps:

- script:name: buildcode: |

/opt/python/cp35-cp35m/bin/python setup.py build- script:

name: testcode: |

/opt/python/cp35-cp35m/bin/python setup.py test- script:

name: packcode: |

/opt/python/cp35-cp35m/bin/python setup.py bdist_wheel- script:

name: auditcode: |

auditwheel repair dist/*.whl -w wheelhouse

7 ソースディストリビューショ

ン sdistとはなにか?• setuptoolsとpipの実装でなんとなく決まっている

• ‘setup.py install‘ ができればsdist?

7.1 setuptoolsがなくてもwheelパッケージは作成できる

• wheelツールはsetuptoolsと独立して作られている

• distlibにもwheelを作成する処理が実装されている

7.2 sdistを考え直す意味• setuptools依存からの脱却• 明確なインストールフロー

7.3 現状のインストール手順

• pipがsdistをダウンロードする• pipがsdistを展開する• pipがsetup.py bdist_wheelを実行する• できあがったwheelパッケージをpipがインストールする

• setup.py install は関係なかった

7.4 PEP 518 – Specifying MinimumBuild System Requirements forPython Projects

• パッケージング方法やそれに必要なツールを支

持する

• pypi上でwheel作成する目的?• パッケージングに必要なツールを記述

• pyproject.toml• TOMLフォーマット

7.5 pyproject.toml[build-system]requires = ["setuptools", "wheel"]

7.6 PEP 516 – Build system abstractionfor pip/conda etc

• ビルドツールの指定や依存性を記述する

• 指定のツールでどのようにビルドするのかも

指定

• pypi.jsonというファイルで話が進んでいるっぽい

• でも多分pyproject.tomの tool セクションが同じものを指しているはず

8 プログラミングPythonパッケージ

• setuptoolsに依存せずにパッケージングしてみよう

8.1 distlibでできること• wheelパッケージ作成• wheelパッケージインストール• メタデータ作成

• パッケージリポジトリからのダウンロード

• インストール済パッケージのリストアップ

8.2 bib - reversed pip• distlibと標準ライブラリのみで実行するパッケージングツール

• 本日作成しました

8.3 distlibを使う準備>>> import sys>>> import os>>> sys.path.append(... os.path.join(... os.getcwd(),... ’distlib-0.2.3-py3-none-any.whl’))>>> import distlib>>> distlib

9 プロジェクトの作成

• bib.init_project

9.1 パッケージメタデータ

• dist-info ディレクトリ• pydist.json/package.json

10 パッケージの作成

10.1 wheelパッケージを作成する• 作業ディレクトリを作成

• パッケージ名.dist-info ディレクトリを作成• dist-info ディレクトリ以下に pydist.json をコピー

• インストール対象を作業ディレクトリにコピー

• distlib.wheelでWheelを作成する

11 パッケージの配布

• 作成したパッケージを公開してインストール可

能にする

• simple package repository形式のサイトで公開する

• ダウンロードしてインストールする

11.1 PEP 503 – Simple Repository API• pypiもこの形式• 登録やアップロード方法は決められてない

• ‘httplib.server‘ などでも実現可能

11.2 wheelファイルをsimple packagerepository形式に配置する

• distlib.wheelでメタデータを取得• パッケージ名でディレクトリを作成

• wheelファイルをコピー• そのディレクトリを対象に ‘httplib.server‘ を立ち上げる

12 インストール

• パッケージをリポジトリからダウンロード

• パッケージのメタデータを読み取る

• Wheelで読み取って、対象ディレクトリにインストール

12.1 パッケージをリポジトリからダウ

ンロードする

• distlib.locators• SimpleScrapingLocator• result.download_urls でURLを取得• 一時ディレクトリに保存

12.2 wheelパッケージをインストールする

• distlib.scripts ScriptMakerを作成• distlib.wheelの install メソッドでインストール

12.3 インストール一覧

• PEP 376 – Database of Installed PythonDistributions

• パッケージによってインストールされたファイ

ルの情報

• どのモジュールがどのパッケージでインストー

ルされたか

• インストール時のファイルのハッシュ

• distlib.database

13 まとめ

• setuptoolsやpipがなくてもパッケージングはできる

• いろんなツールがエコシステムに参加できるよ

うにsdistの定義が検討されている• wheelはがんがん使いましょう