uvとRye

先週にRuffを開発しているAstralがuvを発表しました。

astral.sh

uvは現在のところはvenv, pip, pip-toolsの基本的な機能を提供していますが、将来は"Cargo for Python"になることを目標にしています。

一見すると乱立しているPythonのパッケージ管理ツールにもう一つ加わったように見えますが、Ryeの開発者のArminとuvの開発チームは連携していて、同時に次のような発表をしています。

uv: Python packaging in Rust

Rye Grows With UV | Armin Ronacher's Thoughts and Writings

  • Ryeはもともとより良いパッケージツールがどうあるべきかの実証のために作られていて、中身は既存のツールのツギハギだった
  • Ryeがpip-toolsやvirtualenvの代わりにuvを使うオプション rye config --set-bool behavior.use-uv=true を提供する
  • いつかuvがRyeの機能に追いつくまでRyeの開発は当面続く
  • RyeはAstralが引き継ぎ、Arminも当面Ryeの開発に参加する

ということで、Ryeを使っている人はuvを直接使う必要はなく、試してみたい場合は上記の設定をするのがよさそうです。

私の場合はIssue報告を再現するためにパッケージをインストールしてスクリプトを実行するのにはまだvenvとpipの方が簡単なので、直接uvを使う機会も多いです。その場合の使用感を書いておきます。

venvとuv venvの比較

  • venv の時は alias mkvenv='python3 -m venv --prompt . .venv' というエイリアスを使っていた
  • uv venv はターゲットパスを指定しないと ".venv" を使うので一手間少ない
  • --prompt オプションがなかったのでuvにプルリクエストを送って取り込んでもらった。今朝リリースされた0.1.6に入っている。
  • --prompt . がデフォルトなので、上記エイリアス--prompt . も不要で、 uv venv だけでOK。もうエイリアスいらない。
  • ただし、 rye pin 3.12 してから mkvenv したら rye 管理のPython 3.12を使ってくれるのに、uv venvは which python3.12 で見つからないとエラーになるのでPATHを通しておくなどの手間が必要になる

pipとuv pipの比較

  • pipはvirtualenvを有効にしないとホストのPythonにライブラリをインストールしようとしてしまうが、uv pipは .venv ディレクトリがあるとそっちにインストールしてくれる。
    • activateの手間がない
    • venvの中にpip/uvをインストールしておく必要もないのでvenvの中がより軽量になる
  • とにかくすごく速くて気持ちいい

resticとRustとCACHEDIR.TAG

古いHDDをUSB外付けケースに入れてバックアップ用に利用しているのですが、rsyncを使ったバックアップやmacのTimeMachineが遅くなるので、最近はrestic を使っています。

resticを使っていて感じたメリットをいくつか紹介しておきます。

  • 効率性
    • ファイルをそのままコピーするのではなくgitのようにパックして圧縮して保存するので小さいファイルを大量に作らないしディスクスペースも節約できる。
    • ファイルの更新日時のようなメタデータを利用しているので、差分バックアップするときに遅いHDDからの読み込みを最小限で済ませられるし、mac側の変化があったファイルのスキャンも高速
  • クロスプラットフォーム
    • リポジトリを暗号化するので、exFATの非暗号化ディスクを使えば、macで取得したバックアップの中にあるファイルをWindowsLinuxから救出できる

S3をストレージに使えるくらいなので、HDDの速度が初回バックアップの書き込み時間以外には全く問題にならないくらい高速です。

さて、最近Uvが話題になって触っていたのでRustのプロジェクトを何度かビルドしていたのですが、resticを動かすと差分バックアップでtargetディレクトリがバックアップされているのに気づきました。そして何かいい除外パターンが無いかなとtargetディレクトリを眺めたときに見つけたのが CACHEDIR.TAG ファイルです。調べてみたところ、まさにバックアップから除外するディレクトリを指定するためのファイルのようです。 ~/.cargo/git~/.cargo/registry にも CACHEDIR.TAG が入っているので、Rustの世界では広く普及しているみたいです。

Cache Directory Tagging Specification – Bryan Ford's Home Page

そしてResticもbackupコマンドの --exclude-caches オプションを指定したら自動でこのファイルを見つけてバックアップから除外してくれていました。

Backing up — restic 0.16.4 documentation

そして uv も2日前にvenv作成時にvenvディレクトリ内に CACHEDIR.TAG を作るようになっていました。

Tag created venvs as a cache dir to avoid most of in-project venv downsides · Issue #1648 · astral-sh/uv · GitHub

私はすでに .venv~/.cargo もバックアップ除外パターンに入れてしまっていたのですが、除外パターンというのは設定をミスると必要なファイルのバックアップが取れなくなったりするものなので、CACHEDIR.TAGはどんどん活用していこうと思います。

PEP 723がAcceptされて、pipx runで依存ライブラリがあるスクリプトを実行できるようになっていた

時間がなくて議論を追っていなかったのですが、標準ライブラリ以外に依存したスクリプトを手軽に配布・実行するための提案である PEP 722PEP 723 がしばらく前から議論されていて、先月にPEP 723の方がAcceptされていました。

PEPのサンプルを引用しておきます。 /// script/// で囲われている部分に、必要とするPythonのバージョンと、依存するライブラリを書いています。

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich.pretty import pprint

resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])

pipx は12月の1.3.0からすでにPEP 723をサポートしていて、 pipx run script.py で依存ライブラリを持つスクリプトを実行できるようになっていました。

これに気づいたのは、今話題になっている Uv がテストを実行するのに必要な複数のPythonバージョンをダウンロードするスクリプトが利用していたからです。こういう一回だけ実行するスクリプトを実行するのにpipxはすごく便利です。

https://github.com/astral-sh/uv/blob/d05cb8464a933a4b8e1ebe39988e0209da73ed19/scripts/bootstrap/install.py#L1-L24

ryeでPythonを実行すると "Cannot read termcap database; using dumb terminal settings." が出る

2024/02/26 追記

2/24リリースから改善されたので、下記の対応は不要になりました。

Release 20240224 · indygreg/python-build-standalone · GitHub

Rework of the terminfo database on Linux distributions. ncurses now looks for the terminfo database in /etc/terminfo, /lib/terminfo, and /usr/share/terminfo by default. This should result in the terminfo database being found on many popular Linux distributions, including Debian and RedHat variants. Read: the Python REPL should respond to key presses like backspace properly. In addition, the distribution archive contains a copy of the terminfo database in python/install/usr/share/terminfo. However, this terminfo database won't be used automatically at runtime unless custom code is run to point ncurses at it. See the documentation for more.


Ubuntuでryeを使っていると、タイトルの通りtermcap databaseが見つからないというエラーが発生する。

methane@skyland:~$ /home/methane/.rye/py/cpython@3.11.7/install/bin/python3
Cannot read termcap database;
using dumb terminal settings.
Python 3.11.7 (main, Jan  8 2024, 05:55:31) [Clang 17.0.6 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D

ryeはpython-build-standaloneからpython処理系をダウンロードして使用しているのだけれども、このバイナリがデフォルトで見にいくtermcap databaseの場所がUbuntuと異なるからこのエラーが発生しているらしい。この状態ではいくつかのキーが使えなくなってしまう。

この問題については次のページで説明されていた。

github.com

Debian/Ubuntuの場合であれば、 ~/.profile~/.bashrc などに次のように追記して環境変数でtermcap databaseの場所を教えてやるといい。

export TERMINFO_DIRS=/etc/terminfo:/lib/terminfo:/usr/share/terminfo

Homebrewのmysqlはinnovation releaseを使うので注意

MySQLのInnovation Releaseは新機能の追加だったりdeprecatedなAPIの削除だったりがどんどん入ってきて、しかもバグ修正リリースは存在せずに次のInnovation Release待ちになる。古典的な言い方をすればアルファ版的な存在だ。

Homebrewユーザーは、 brew install mysql をするとこの Innovation Release を自動で使うようになるので、先行して問題を発見して報告する意気込みがないのであれば brew install mysql@8.0 でLTSを使い続けることをお勧めする。

先日リリースされた MySQL 8.3 では、クライアントC APImysql_set_ssl() が削除された。これが公式にDeprecateされたのは、2023-10-25リリースの8.0.35/8.2だ。

MySQL :: MySQL 8.0 Release Notes :: Changes in MySQL 8.0.35 (2023-10-25, General Availability)

これでPythonのmyslqclientのビルドが通らなくなって週末に対応したが、この種の問題に対して多くのOSSメンテナに素早い対応は期待しないでほしい。

このブログに乗せているコードは引用を除き CC0 1.0 で提供します。