はじめに
やけにカラスが騒がしいな... nikkieです
シェイクス丸🐦⬛に告げられ、uv 0.4.27のリリースを機に、PEP 735 (2024/10/10 Accepted🎉)を知りました。
uvはもうサポートしたそうで、まずはこのPEPが何を提案しているかを掴みます。
目次
PEP 735 – Dependency Groups in pyproject.toml
「Dependency Groups」なるものを導入しました。
pyproject.toml
に以下のように書けるようになります1(執筆時点ではuvのみがサポート。増えていくはずです)
[dependency-groups] test = ["pytest>7", "coverage"]
PEPにはrequirements.txt
を使う方法とextraを使う方法との違いが述べられています。
私はこのうちextraを使う方法との違いを以下のように理解しました2。
このあと詳しく見ていきます
- extraを使う方法は再配布するプロジェクトにしか適用できないが、Dependency Groupsは再配布しないプロジェクトでも利用できる3
- 上の例のpyproject.tomlを、データサイエンスプロジェクトやDjangoで作るWebアプリにも設けられます!
- extraを使う方法と違って、Dependency Groupsはプロジェクトをインストールせずに、指定したGroupだけをインストールできる
- 上の例では、プロジェクト自体をインストールせずに、pytestとcoverageだけをインストールするように指定できます
※PEP 735はガッツリ読み込めているわけではないので、誤解しているようでしたらお知らせください🙏
nikkieの理解
PEP 735より前(extraを使う方法)
既存のライブラリを例にします。
メンテナしているSpeechRecognitionですが、PyPIで左カラムのメタデータにご注目!
Provides-Extra:
audio
,dev
,whisper-api
,whisper-local
これがextraです。
このライブラリはpyproject.toml
に移行しきれていなくてsetup.cfg
なのですが4、
https://github.com/Uberi/speech_recognition/blob/3.11.0/setup.cfg#L6-L16
pyproject.toml
で表すと以下のように定義しています
[project.optional-dependencies] dev = ["flake8", "rstcheck"] audio = ["PyAudio>=0.2.11"] whisper-local = ["openai-whisper", "soundfile"] whisper-api = ["openai"]
- ライブラリのユーザが、オプションの機能を有効にするために指定
- ライブラリの開発者が、環境構築のために指定
- 静的解析ツール一式をインストールしたい:
pip install -e SpeechRecognition[dev]
-e
はeditable install(ソースコードをsite-packages下にコピーしないことで、コードの変更を再インストール無しで反映できるインストールです)
- 静的解析ツール一式をインストールしたい:
extraとして並んでいますが、実は対象者が違っていることを今回のPEPを機に知りました
PEP 735以後
今の私の理解では、以下のようにできると思われます
[project.optional-dependencies] audio = ["PyAudio>=0.2.11"] whisper-local = ["openai-whisper", "soundfile"] whisper-api = ["openai"] [dependency-groups] dev = ["flake8", "rstcheck"]
extra(project.optional-dependencies
)とDependency Groupsを分けました。
- extraはライブラリのユーザに、ライブラリのオプション機能の選択肢として見せたいので残した
- PEP 735はextra(
project.optional-dependencies
)をdeprecateするものではないと理解しています
- PEP 735はextra(
- devをDependency Groupsとすることで、ライブラリの開発者の環境構築をライブラリのユーザに見せずに済む
- ライブラリの開発者はdev groupだけのインストールも可能
(書いてみたことでより分かったのですが、)Dependency Groupsはproject
とは無関係ですから、再配布しないプロジェクトの場合も書くことができますし5、groupだけをインストールできるのでありがたいです。
終わりに
PEP 735提案で採択されたDependency Groupsを完全に理解しました。
私は再配布できるプロジェクトの経験が多く「別にextraでいいのでは」と思っていたクチです。
PEPを読んでextraには対象者が2通りいたことに気づき、再配布しないプロジェクトのpyproject.tomlにも書けることを知り、妥当な提案と思えています。
もしかして各種パッケージマネージャでプルリクチャンスですか!?!?(例えばpipはいつサポートするんだろう?)
PEP 735はAppendixで他の言語の状況にも触れていますし、Deferred Ideasもありますから、もう少し読んでみたい感はあります。
採択に至る議論も気になるところです
- https://peps.python.org/pep-0735/#rationale の例です↩
- https://peps.python.org/pep-0735/#limitations-of-extras を参照しています↩
- 私見6の2と3のことです ↩
-
全部
pyproject.toml
の例は sphinx-new-tab-link ですが、こちらはどのextraもライブラリの開発者向けです(dev, lint, testing, typecheck) ref: https://github.com/ftnext/sphinx-new-tab-link/blob/v0.6.1/pyproject.toml#L29-L33↩ - PEPには「Dependency Groups are not Hidden Extras」とあり、この記事でこの点も伝わっていたらいいなと思っています↩
- uvの言葉だとそれぞれ「ライブラリ」と「アプリケーション」です(ただしuvには再配布できるアプリケーションもあります) ↩