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

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

Apr 13, 2017

Download

Software

Atsushi Odagiri
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: パッケージングを支える技術 pyconjp2016

2016年9月21日

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

PyCon JP 2016

Atsushi Odagiri

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

1 お前だれよ

• 小田切篤

• Beproud, Inc.

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

2 これまでのお話

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

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

3 アジェンダ

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

• ソースパッケージ

• バイナリパッケージ

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

よう

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

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

ツール

• PyPA ってなに?

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

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

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

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

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

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

4.3 setuptools• 配布物を作成する

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

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

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

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

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

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

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

4.6 pip• インストーラ

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

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

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

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

4.8 ツールの導入方法

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

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

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

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

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

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

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

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 でツールを導入する

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

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

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

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

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

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

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

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

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

ル先

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

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

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

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

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

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

• easy_install が活用していた

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

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

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

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

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

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

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

6.1 PEP 427 – The Wheel BinaryPackage Format 1.0

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

• 既に利用されている

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

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

6.2 PEP 513 – A Platform Tag forPortable Linux Built Distributions

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

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

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

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

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

いか?

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

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

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

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

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

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 プラットフォーム

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

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

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

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

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

• libnsl.so.1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

7.4 PEP 518 – Specifying MinimumBuild System Requirements forPython Projects

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

持する

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

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

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

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

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

7.6 PEP 516 – Build system abstractionfor pip/conda etc

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

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

指定

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

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

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

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

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

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

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

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

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

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

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

• 本日作成しました

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

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

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

9 プロジェクトの作成

• bib.init_project

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

9.1 パッケージメタデータ

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

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

10 パッケージの作成

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

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

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

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

• distlib.wheelでWheelを作成する

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

11 パッケージの配布

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

能にする

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

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

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

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

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

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

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

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

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

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

12 インストール

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

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

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

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

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

ンロードする

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

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

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

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

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

12.3 インストール一覧

• PEP 376 – Database of Installed PythonDistributions

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

ルの情報

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

ルされたか

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

• distlib.database

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

13 まとめ

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

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

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