👻

rye → uv移行を検討する(注意点有り!)

2024/09/19に公開

uvがryeの機能を対応し始めた

1ヶ月ほど前にuvがPythonプロジェクトをスムーズに管理出来るようになった記事が公開されました

https://astral.sh/blog/uv-unified-python-packaging

私はこれまでrye + uvでプロジェクト管理していましたが、この機会にuvに移行できないものかと考えました。
今回はryeからuvに移行できるか検証します。

結論

スクリプト機能rye run {script}を使っていないのであれば移行可能

使っている人は様子見安定。

移行できるか検討する

では、ryeからuvに移行できるか検証してみます。

検証時のバージョンは👇️の通り。検証日は2024/09/19です。

uv --version
# uv 0.4.12 (2545bca69 2024-09-18)

rye --version
# rye 0.39.0
# commit: 0.39.0 (bf3ccf818 2024-08-21)
# platform: macos (aarch64)
# self-python: cpython@3.12.2
# symlink support: true
# uv enabled: true

https://zenn.dev/nowa0402/articles/85833db7ff2e13

プロジェクト作成 ~ パッケージ追加

基本動作。まずはryeから
細かいオプションは一旦抜きで書きます。

# プロジェクト作成
rye init project

# パッケージ追加
rye add pandas

# 反映
rye sync

次はuv。こちらもだいたい一緒

# プロジェクト作成
uv init project

# パッケージ追加
uv add pandas

使えるコマンドは似ているのでスムーズに移行できそう

ワークスペース管理はuvの方が楽

rye, uvともにワークスペース管理ができます。

まずはrye。事前準備としてワークスペース対象のディレクトリをpyproject.tomlに記載します

pyproject.toml
[tool.rye.workspace]
# glob形式で記入
members = ["services/*"]

プロジェクトの追加とパッケージの追加。
ryeは当該プロジェクトのディレクトリに移動して追加する必要があります。

# プロジェクト登録
cd services
rye init --py 3.12 --virtual project_a # --py {Pythonバージョン} --virtualで仮想環境設定

# パッケージ追加
cd project_a # ワークスペースまで移動することが必要
rye add pandas

続いてuv。事前準備はryeとほぼ一緒

pyproject.toml
[tool.uv.workspace]
members = ["services/*"]

プロジェクトの追加とパッケージの追加。
uvは--packageオプションを指定することで、ディレクトリを移動しなくてもパッケージを追加することができます。
これはryeより便利だなと思いました。

# プロジェクト追加
cd services
uv init --app project_a

# パッケージ追加
uv add --package project_a pandas

uvで便利なのはrequirements.txtの出力

uvを使っていて便利なのはpyproject.tomlに記載してあるパッケージからrequirements.txtを出力することです

依存関係のインストールにrequirements.txtの出力が必要なときに使えます。

# pyproject.tomlからrequirements.txtを出力する
uv pip compile pyproject.toml -o requirements.txt

ryeの場合、lockファイルからsedコマンドで吐き出すやり方があります。

sed '/-e/d' requirements.lock > requirements.txt

なお、この方法はryeリポジトリのRye + Dockerでディスカッションされていた内容のアンサーになっています。参考にさせていただきました。

ryeで出来てuvで出来ないこと

ここまでの通り、ryeで出来ることはuvでも出来ることが分かりました。
移行出来そうかな・・・と思いました。が、ここで大きな壁があります。
それは スクリプト実行機能 です。

rye run {script}

ryeではpyproject.toml[tool.rye.scripts]を追加することができます。

pyproject.toml
[tool.rye.scripts]
compile = "uv pip compile pyproject.toml -o requirements.txt"
test = "pytest -vv tests"

check = { chain = ["check:ruff", "check:mypy"] }
"check:ruff" = "ruff check --config pyproject.toml src"
"check:mypy" = "mypy src --config-file=../../pyproject.toml"

rye run {script}で呼び出しできます。
チェイン機能もあるのでめっちゃ便利。

# pytest -vv tests を呼び出す
rye run test

# "check:ruff"と"check:mypy"を呼び出す
rye run check

uvでこれが出来るのか。結論 「対応中」 みたいです。

[project.scripts]という項目はありますが、想定どおりに動きません。
ビルドシステムのときに使える要素のようです。

https://docs.astral.sh/uv/concepts/projects/#packaged-applications

pyproject.toml
[project.scripts]
hello = "echo hello"
# 想定通り動かない(期待値は"hello"と表示される)
uv run --package project_a hello

非常に惜しい!あと少しでryeから卒業できそうなのに…。
これについては他の開発者も同様の悩みがあったようで、Issueが立てられています。積極的にディスカッションされているっぽいので近いうちに実装されるかもしれません…!

https://github.com/astral-sh/uv/issues/5903

まとめ:ryeからuvに移行出来るか

👇️に当てはまる人は移行を考えても良さそうです

  • 現在パッケージマネージャー(pipenv,poetry、rye)を使っていない人
  • pipenvやryeでスクリプトを使わない運用をしている

私みたいにスクリプト機能を使いたい人は様子見すると良さそうです。
(早くIssue解決されないかなあ…)

参考

GitHubで編集を提案

Discussion