Slide 1

Slide 1 text

使い続けるための Pythonプロジェクト の始め⽅ ゆゆ君(@Hyuyu_kun) in あくあたん工房 2022/07/29

Slide 2

Slide 2 text

“環境を再現できる方法と使い方を残す“ 2

Slide 3

Slide 3 text

“環境を再現できる方法と使い方を残す“ 3 使い方は頑張ってREADMEを書いて…。

Slide 4

Slide 4 text

使い続けるためには n 開発環境を再構築できる方法を用意する • 突然パソコンが壊れた • 動く環境がこれしかない • 使いたいけど、エラーが出て使えない n 再構築できるようにしておくと • なんかわからんけど、動かなくなった時に気軽に環境を吹き飛ばせる • 一緒に開発するメンバーと同じ環境で揃えられる • バグを含めて、同じようにプログラムを動かせる 4

Slide 5

Slide 5 text

過去記事の掘り返し n 公開さえすればいいってもんじゃない • https://poyo.hatenablog.jp/entry/2019/08/16/000000 • From あくあたん工房お盆休みアドベントカレンダー • > 研究で開発したツールを公開するのはとても良いこと • > 頼むから必要な依存関係の情報を残してくれ • > 頼むからREADMEを書いてくれ • > 頼むからライセンスを明記してくれ • > 頼むからDockerイメージになんでも突っ込まないでくれ 5

Slide 6

Slide 6 text

Pythonを使う上で気をつけないといけないことは? 6

Slide 7

Slide 7 text

Pythonのバージョン 7

Slide 8

Slide 8 text

Pythonディストリビューション(まだいっぱいある) n CPython • Pythonといえば、大体これ。C言語で実装されている。 • C言語によるPython拡張APIがあるので、これを利用して様々なライブラリが開発されている。 n Jython • JavaによるPython実装。PythonコードをJavaのバイトコードにコンパイルできる。 n PyPy • Pythonインタープリタ自身がPythonで書かれている。 • CPythonより圧倒的に早い。AtCoderでもCPythonでは無理でもPyPyなら通ることがある。 • C言語によるPython拡張APIの完全なサポートはない。 8

Slide 9

Slide 9 text

Pythonのバージョン n Python2 • Python2は既にEOL(2020/01/01) • とはいえ、Python3に移行出来ていないシステムやライブラリは存在する。 n Python3 • Python3でも、Python 3.xのバージョンが違えば、動かないコードが出てくる。 • 例えば、numpy 1.22.0からはPython 3.7はサポートされなくなりました。 9 x = "Python" print("Hello World, {}".format(x)) print(f"Hello World, {x}") # fstring (Python 3.6 <= version) # >>> Hello World, Python # >>> Hello World, Python

Slide 10

Slide 10 text

パッケージのバージョン 10 numpy, matplotlib, pandas, scikit-learn, pytorch,…

Slide 11

Slide 11 text

Pythonのパッケージ管理ツール n pip • Pythonの標準で付属しているパッケージ管理ツール • > より正確にはパッケージインストーラである。 • > pipは具体的に依存treeを生成するような依存解決は行わず、順番にインストールしていき、 サブモジュールの依存関係に問題があった場合は上書きする事で解決する。 11 > https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715

Slide 12

Slide 12 text

依存関係 n 依存関係を解決できない例 • 要件を満たせないので無理矢理インストールしても正しく動作する保証はない • Package1の依存関係 • hoge >= 2.1.* • fuga <= 1.3.* • Package2の依存関係 • hoge >= 2.1.* • fuga >= 2.0.* n 解決方法 • Package1をアップグレードして、fuga >= 2.0.*に対応したバージョンを利用する • Package2をダウングレードして、fuga <= 1.3.*でも利用できるバージョンを利用する 12

Slide 13

Slide 13 text

Pythonのパッケージ管理ツール n pip • Pythonの標準で付属しているパッケージ管理ツール • > より正確にはパッケージインストーラである。 • > pipは具体的に依存treeを生成するような依存解決は行わず、順番にインストールしていき、 サブモジュールの依存関係に問題があった場合は上書きする事で解決する。 n Anaconda • pipが使うPyPIとは別に、独自のPyPIミラーを持つ。 • > 機械学習向けにCUDA環境に合わせたパッケージの取得、高速なnumpyパッケージなど、 環境に応じた最も良いものをインストールしてくれる • > numpy anaconda 早い – Google 検索 • ありがたいけど、自分が使っているのはどのパッケージなのか?が見えにくい。 13 > https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715

Slide 14

Slide 14 text

やるべきこと n 利用しているPythonのバージョンは何かを残すこと。 n 利用しているパッケージは何か、だけでなく、 利用しているバージョンと、その依存関係を残すこと。 14

Slide 15

Slide 15 text

asdf-python + poetryでPython環境を作る n asdf • バージョン管理ツール • Pythonのバージョン(2.x, 3.x, anaconda, pypy, …)を管理する • Python以外にも様々なプログラミング言語、ツールのバージョン管理ができる。 • というか、Pythonに限らず、バージョン管理した方が良いので、こうゆうのを使ってほしい。 n pyenvの名前をよく聞くけど? • pyenvはPythonのバージョン管理をするツール • pyenvが利用しているpython-buildは、pyenv無しでもPythonのインストールツールとして 利用できる。 • asdf-pythonはこのpython-buildを使っているので、やっていることはほぼ同じ。 • 安心(?)して移行しよう。 15

Slide 16

Slide 16 text

asdf-python + poetryでPython環境を作る n poetry • パッケージ管理ツール • 依存解決、lockファイル生成、仮想環境、パッケージングができる。 • パッケージをbuildして、PyPIへpublishして公開までpoetryでできる。 • 従来のrequirements.txt、setup.py, setup.cfgなどを、pyproject.tomlに集約する。 n pipenv • これの登場で依存関係の解決などに大きな影響を与えた偉大なツール • 自前でバージョンhashを計算するので、依存関係がpoetryより遅くなってしまう • パッケージングの機能は無い • 正直、ここは今回の話にはあまり関係がないので、別にpipenvでもできることは十分できる。 16

Slide 17

Slide 17 text

asdfのインストール n ドキュメントにいろんな環境での方法が書いてあるので見て • https://asdf-vm.com/guide/getting-started.html#getting-started n Ubuntu, Bash & Gitを想定 17 // 1. Install Dependencies $ sudo apt install curl git // 2. Download asdf $ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.2 // 3. Install asdf $ echo ". $HOME/.asdf/asdf.sh" >> $HOME/.bashrc $ source $HOME/.bashrc // 4. Install asdf-python $ asdf plugin add python

Slide 18

Slide 18 text

asdfでPythonのインストール 18 // UbuntuでPythonをビルドするための依存パッケージ // https://devguide.python.org/getting-started/setup-building/index.html#install-dependencies $ sudo apt-get install build-essential gdb lcov pkg-config ¥ libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev liblzma-dev ¥ libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev ¥ lzma lzma-dev tk-dev uuid-dev zlib1g-dev // asdfのPython pluginをインストール $ asdf list all python // Python 3.10.5 をインストール $ asdf install python 3.10.5

Slide 19

Slide 19 text

asdfでPythonの切り替え 19 // global設定は、system全体で使われるようになるのであまり変更しないほうがいい // 以下のどちらかで設定しておく // (1) Ubuntuならapt、macOSならbrewでインストールしたPythonがあるならそれを指定しておく $ asdf global python system // (2) 一度Pythonのバージョンを指定しておき、あまり変更しないようにする<-僕はこうしてる $ asdf global python 3.10.5 // 現在のディレクトリ内で利用するPythonのバージョンを指定する // == プロジェクトごとに利用するPythonを切り替えられる $ asdf local python 3.10.5

Slide 20

Slide 20 text

asdfで指定したPythonのバージョン情報 n .tool-versionsに記録される • global設定は $HOME直下、local設定はコマンドを実行したディレクトリ直下にある • 中身はただのテキストファイル n プロジェクト内の.tool-versionsは git add & git commit して おくと良い!!!! 20 // global設定 $ ls -a $HOME … .tool-versions … $ cat $HOME/.tool-versions python 3.10.5

Slide 21

Slide 21 text

python コマンド n python2, python3, python コマンド • python2 : Python 2.xのどれか • python3 : Pytohn 3.xのどれか • python : Python 2.x もしくは Python 3.x のどれか n どれかって何。 • Python 3.9.xは、python3.9ってコマンドがいる。 • Python 2.7.xは、python2.7ってコマンドがいる。 • python2, python3, pythonコマンドは、利用できるPythonの バージョンのどれかを指定しているだけ。 n どのバージョンが指定されているのか?を 気にした方がいい。 21

Slide 22

Slide 22 text

poetryのインストール n asdfを使ってインストールする • asdfを使ってPythonのバージョンを管理している状態では、公式ドキュメントの インストール方法を使うと、そのPythonのバージョンにpoetryがインストールされる • systemで利用できるpoetryをインストールするにはasdfを使って入れると良い 22

Slide 23

Slide 23 text

poetryのインストール 23 // Install poetry plugin $ asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git // Install poetry $ asdf list all poetry $ asdf install poetry 1.1.14 // 環境ごとに設定が違うので、表示されるログをよく見て追記して Poetry (1.1.14) is installed now. Great! To get started you need Poetry's bin directory ($HOME/.asdf/installs/poetry/1.1.14/bin) in your `PATH` environment variable. To configure your current shell run `source $HOME/.asdf/installs/poetry/1.1.14/env` $ cat "source $HOME/.asdf/installs/poetry/1.1.14/env" >> $HOME/.bashrc $ source $HOME/.bashrc

Slide 24

Slide 24 text

poetryの設定 24 // プロジェクトのディレクトリ内に仮想環境のフォルダ `.venv` を作成する $ poetry config virtualenvs.in-project true

Slide 25

Slide 25 text

poetryを使った開発環境の手順 n 1. 利用するPythonのバージョンを決める • asdf local python 3.x.x n 2. pyproject.tomlを作成する • poetry init n 3. poetryでパッケージを追加 • poetry add PACKAGE_NAME n x. poetryでPythonの仮想環境を作り、仮想環境を有効化 • poetry shell 25

Slide 26

Slide 26 text

poetryでpyproject.tomlを作成 n pyproject.tomlの作成で必要な情報 • Package name • pip listなど、パッケージ一覧を表示したときに表示される名前 • Version • パッケージのバージョン • Description • パッケージの説明 • Author • 作者の名前とメールアドレス • License • MIT License, Apache License, BSD Licenseなど。実験などPrivateな利用の場合は特に指定しなくて良い。 • Compatible Python versions • ^3.10とすると、>=3.10 <4.0のPythonバージョンが対象となる。 • Python 3.10.xのみ対象にしたい場合は~3.10とする。詳しくは、ドキュメントを参照。 26

Slide 27

Slide 27 text

poetryでpyproject.tomlを作成 27

Slide 28

Slide 28 text

poetryでパッケージのインストール n pipの代わりにpoetryを使う • poetry add numpy n 開発環境向けでしか利用しないパッケージには `--dev` • poetry add black flake8 isort mypy --dev 28

Slide 29

Slide 29 text

Poetryでパッケージインストール 29

Slide 30

Slide 30 text

dependenciesとdev-dependencies 30

Slide 31

Slide 31 text

中級者向け n コードをクリーンに保つ n Formatter • black, isort • blackはスタイルを細かく調整できない。むしろ、みんな同じようなフォーマットを強制できて良い。 n Linter • flake8 • 有名なLinterの1つ。blackのフォーマットに合わせるには少し調整が必要。 n Type Checker • mypy • Pythonでもつけられるようになったタイプヒントを使っていくために必要なツール。 31

Slide 32

Slide 32 text

設定方法 32 # pyproject.tomlの末尾に追加 [tool.isort] profile = "black" [tool.mypy] # common python_version = 3.10 check_untyped_defs = true show_column_numbers = true show_error_context = true ignore_missing_imports = true disallow_untyped_defs = true # warning warn_return_any = true warn_unused_configs = true warn_redundant_casts = true # setup.cfgの末尾に追加 # flake8はまだpyproject.tomlに対応していない [flake8] # e203: black treats : as a binary operator # e231: black doesn't put a space after , # e501: black may exceed the line-length to follow other # style rules # w503 or w504: # either one needs to be disabled to select w error # codes ignore = E203,E231,E501,W503 select = B,B950,C,E,F,W per-file-ignores = # imported but unused __init__.py: F401 > https://qiita.com/edge-m/items/846715217fc3dd481a84

Slide 33

Slide 33 text

使い方 33 // black // フォーマットを適用 $ poetry run black . // チェックのみ $ poetry run black . --check --diff // isort // フォーマットを適用 $ poetry run isort . // チェックのみ $ poetry run isort . --check --diff // flake8 $ poetry run flake8 . // mypy $ poetry run mypy .

Slide 34

Slide 34 text

mypyのタイプヒント n タイプヒントの付け方がわからなくて困ることがしばしば • ライブラリが対応していないこともあるので、無理な場合は思い切って # type: ignore してもいい • 変に時間を溶かさないように 34

Slide 35

Slide 35 text

GitHub ActionsでCI n Format、Lintの実行 n 複数バージョンのPython、複数のOSでテスト • GitHub Actionsのmatrix-*で実現できる 35

Slide 36

Slide 36 text

GitHub Actions workflow例 36 name: CI on: push: pull_request: jobs: static-analysis: strategy: matrix: os: ["ubuntu-latest", "macos-latest"] python-version: [3.8, 3.9] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install Poetry uses: snok/install-poetry@v1 with: virtualenvs-create: true virtualenvs-in-project: true - name: Install dependencies run: poetry install --no-interaction --no-root - name: Install library run: poetry install --no-interaction - name: Check black run: poetry run black . --check –diff - name: Check isort run: poetry run isort . --check –diff - name: Check flake8 run: poetry run flake8 . - name: Check mypy run: poetry run mypy .

Slide 37

Slide 37 text

まとめ n 使い続けるためには、環境を再現する方法と使い方を残すこと。 n Pythonでやるべきこと • 1. 利用しているPythonのバージョンは何かを残すこと。 • 2. 利用しているパッケージは何か、利用しているバージョンと、その依存関係を残すこと。 n 具体的な方法 • 1. asdf-pythonを使って、Pythonのバージョン管理をする。 • 2. poetryを使ってパッケージのバージョンと依存関係を管理する。 n コードをクリーンに保つためにツールを活用する。 37

Slide 38

Slide 38 text

使い続けられるPythonプロジェクトにしていこう 38

Slide 39

Slide 39 text

ありがとうございました

Slide 40

Slide 40 text

参考文献 n エキスパートPythonプログラミング 改訂3版 n 公開さえすればいいってもんじゃない • https://poyo.hatenablog.jp/entry/2019/08/16/000000 n Python開発環境メモ(2019) • https://poyo.hatenablog.jp/entry/2019/03/19/133350 n pipとpipenvとpoetryの技術的・歴史的背景とその展望 • https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715 n 中級者へのModern Python • https://zenn.dev/ganariya/articles/intermediate-python n 【2021】モダンなPython開発環境の紹介 • https://qiita.com/edge-m/items/846715217fc3dd481a84 40

Slide 41

Slide 41 text

参考文献 n 【2020年新人研修資料】ナウでヤングなPython開発入門 • https://speakerdeck.com/stakaya/2020nian-xin-ren-yan-xiu-zi-liao-nauteyankunapythonkai-fa-ru-men n pyenv/pyenv python-build • https://github.com/pyenv/pyenv/tree/master/plugins/python-build n asdf-vm/asdf • https://github.com/asdf-vm/asdf n danhper/asdf-python • https://github.com/danhper/asdf-python n python-poetry/poetry • https://github.com/python-poetry/poetry 41