a12ff503a287c43764d17c7ba1fbf270e89a00a1
nix/uv2nix/uv2nix\343\202\222\344\275\277\343\201\243\343\201\237Nix + uv\343\201\247\343\201\256Python\347\222\260\345\242\203\346\247\213\347\257\211.md
| ... | ... | @@ -0,0 +1,121 @@ |
| 1 | +# このページについて |
|
| 2 | + |
|
| 3 | +nixを使ってみようかなーと思っていたところ、nixとuvを結合するuv2nixというツールがあるのを知り、NotebookLMでまとめてみました。 |
|
| 4 | +この文章はNotebookLMによって生成されました。 |
|
| 5 | + |
|
| 6 | +## ライセンスについて |
|
| 7 | + |
|
| 8 | +[1]のライセンスがCC BY 4.0であることに基づき、この文章もCC BY 4.0でライセンスされています。 |
|
| 9 | + |
|
| 10 | +- 参照: |
|
| 11 | + - [1] [NixCon 2025 - Python packaging with nixpkgs, pyproject.nix & uv2nix - YouTube](https://youtu.be/5yvDZnwmQSs?si=4rax_UKfTueq36Cl) |
|
| 12 | + - ライセンス: CC BY 4.0 |
|
| 13 | + - [2] [Getting started - uv2nix](https://pyproject-nix.github.io/uv2nix/usage/getting-started.html) |
|
| 14 | + |
|
| 15 | +--- |
|
| 16 | + |
|
| 17 | +# NixとPythonパッケージ管理:uv2nixとflake.nixの役割 |
|
| 18 | + |
|
| 19 | +## 1. なぜ `flake.nix` (Nixpkgs) だけで管理しないのか |
|
| 20 | +従来のNixpkgsを使用したPython開発(`flake.nix`のみでの管理)には、主に以下の技術的・実用的な課題が存在します。 |
|
| 21 | + |
|
| 22 | +* **二重管理と非効率性**: Python標準の `pyproject.toml` があるにもかかわらず、その内容(依存関係)を `flake.nix` 内の `withPackages` 引数として手動で翻訳・記述する必要があり、非効率(unergonomic)です,。 |
|
| 23 | +* **開発ツールの非互換性**: Nixpkgsは標準的な仮想環境(virtual environment / venv)を作成しません。その結果、標準的なvenvの存在を前提とするLSP(例: Pyright)やエディタの補完機能が正常に動作しない場合があります。 |
|
| 24 | +* **バージョンの制約**: Nixpkgsに収録されているPythonパッケージセットのバージョン(例: Jinja2 3.1.5)が強制されるため、プロジェクトが要求する特定のバージョン(例: 3.1.6)と不整合が生じることがあります,。 |
|
| 25 | +* **環境変数による汚染(Footguns)**: NixpkgsのPython環境は `PYTHONPATH` を使用して依存関係を伝播させます。これにより、開発環境に入った際、Nixpkgs側の依存関係が優先されてしまい、意図しないライブラリが読み込まれる問題が発生します,。 |
|
| 26 | + |
|
| 27 | +## 2. uv2nix とは |
|
| 28 | +`uv2nix` は、Rust製の高速なPythonパッケージマネージャ `uv` のワークスペースを取り込み、純粋なNixコード(Pure Nix code)を使用して動的にNixのDerivation(ビルド定義)を生成するツールです。 |
|
| 29 | + |
|
| 30 | +* **PyPIからの直接構築**: NixpkgsのPythonパッケージセットに依存せず、`uv.lock` ファイルに基づいてPyPIから直接ソースやバイナリ(Wheel)を取得し、環境を構築します。 |
|
| 31 | +* **標準的な仮想環境の提供**: Nix独自の環境構造ではなく、標準的な仮想環境(bog-standard virtual environment)を作成するため、LSPなどの既存のPython開発ツールがそのまま動作します。 |
|
| 32 | +* **ワークスペースとEditableインストール**: 複数のパッケージを含むワークスペースや、開発中のローカルパッケージのEditableインストール(編集可能モード)に対応しており、スクリプトなどがパスに通った状態で開発できます,。 |
|
| 33 | +* **基盤技術**: `pyproject.nix` ライブラリとそのビルドインフラストラクチャをベースに構築されています。 |
|
| 34 | + |
|
| 35 | +--- |
|
| 36 | + |
|
| 37 | +# チュートリアル:uv2nix による Python 開発環境の構築 |
|
| 38 | + |
|
| 39 | +このガイドでは、Rust製の高速なパッケージマネージャ `uv` と Nix を組み合わせ、再現性が高く、かつ既存の開発ツール(LSP等)と互換性のある開発環境を構築します。 |
|
| 40 | + |
|
| 41 | +## 1. 準備とプロジェクトの初期化 |
|
| 42 | + |
|
| 43 | +まだ `uv` がインストールされていない場合、Nix を使って一時的なシェルに入り、プロジェクトの雛形を作成します。 |
|
| 44 | + |
|
| 45 | +**コマンド:** |
|
| 46 | +```bash |
|
| 47 | +# 1. uv と python が使えるシェルに入る |
|
| 48 | +nix-shell -p python3 uv |
|
| 49 | + |
|
| 50 | +# 2. プロジェクトの初期化(pyproject.toml, .python-version 等が作成される) |
|
| 51 | +uv init --app --package |
|
| 52 | + |
|
| 53 | +# 3. ロックファイルの生成 |
|
| 54 | +uv lock |
|
| 55 | +``` |
|
| 56 | + |
|
| 57 | +## 2. `flake.nix` の設定(環境の定義) |
|
| 58 | + |
|
| 59 | +`uv2nix` の核心は、`uv.lock` を読み込んで Nix のパッケージセットに変換することです。以下の概念を組み合わせて `flake.nix` を記述します。 |
|
| 60 | + |
|
| 61 | +1. **ワークスペースのロード**: プロジェクト全体(`uv.lock`)を解析します。 |
|
| 62 | +2. **オーバーレイの作成**: `mkPyprojectOverlay` を使い、`uv.lock` の情報を Nix のビルド指示書(Derivation)に変換します。ここでは「Wheel(バイナリ)」または「sdist(ソース)」の優先度を指定できます。 |
|
| 63 | +3. **Pythonセットの構築**: 基本となる Python に、ビルドシステム(setuptools等)と上記のオーバーレイを結合します。 |
|
| 64 | +4. **Editable モード(開発用)**: 開発中はソースコードの変更を即座に反映させるため、`mkEditablePyprojectOverlay` を使用して、ソースを仮想環境にリンクさせます。 |
|
| 65 | + |
|
| 66 | +### 手順 2-1: `flake.nix` の作成 |
|
| 67 | + |
|
| 68 | +以下のファイルを`flake.nix`として保存します。 |
|
| 69 | +[uv2nix/templates/hello-world/flake.nix at master · pyproject-nix/uv2nix](https://github.com/pyproject-nix/uv2nix/blob/master/templates/hello-world/flake.nix) |
|
| 70 | + |
|
| 71 | +## 3. パッケージの追加と反映(日常のフロー) |
|
| 72 | + |
|
| 73 | +`uv2nix` を導入後のパッケージ管理は、Python 標準のワークフローに従います。`flake.nix` を編集する必要はありません。 |
|
| 74 | + |
|
| 75 | +### 手順 3-1: 依存関係の定義 |
|
| 76 | +`pyproject.toml` を編集し、追加したいライブラリを記述します。 |
|
| 77 | + |
|
| 78 | +```toml |
|
| 79 | +[project] |
|
| 80 | +dependencies = [ |
|
| 81 | + "requests", |
|
| 82 | + "numpy", |
|
| 83 | +] |
|
| 84 | +``` |
|
| 85 | + |
|
| 86 | +### 手順 3-2: ロックファイルの更新 |
|
| 87 | +ターミナルで以下を実行し、`uv.lock` を更新します。 |
|
| 88 | + |
|
| 89 | +```bash |
|
| 90 | +uv lock |
|
| 91 | +``` |
|
| 92 | + |
|
| 93 | +### 手順 3-3: 環境の再構築 |
|
| 94 | +開発シェルに入り直します。`uv2nix` が自動的に新しい `uv.lock` を読み込み、環境を構築します。 |
|
| 95 | + |
|
| 96 | +```bash |
|
| 97 | +nix develop |
|
| 98 | +``` |
|
| 99 | + |
|
| 100 | +この環境は**標準的な仮想環境(bog-standard virtual environment)**として構築されるため、VSCode や Pyright などの LSP ツールがそのまま動作し、補完も効きます。 |
|
| 101 | + |
|
| 102 | +## 4. トラブルシューティング:C拡張/バイナリライブラリ |
|
| 103 | + |
|
| 104 | +NumPy や PyQt のような C/C++ ライブラリに依存するパッケージを追加した場合、PyPI からダウンロードされた Wheel(バイナリ)が動かないことがあります。 |
|
| 105 | + |
|
| 106 | +* **自動修正**: 通常、`uv2nix` は `autoPatchelfHook` を使用して、Linux 上でバイナリが動くように自動修正を試みます。 |
|
| 107 | +* **手動修正(オーバーライド)**: それでも「ライブラリが見つからない(例: `libstdc++.so.6 missing`)」というエラーが出る場合は、`flake.nix` で不足しているライブラリを手動で追加する必要があります。 |
|
| 108 | + |
|
| 109 | +**修正例 (`flake.nix` 内のオーバーレイ):** |
|
| 110 | +```nix |
|
| 111 | +(final: prev: { |
|
| 112 | + numpy = prev.numpy.overrideAttrs (old: { |
|
| 113 | + # 不足しているライブラリ (例: zlib, stdenv.cc.cc.lib) を buildInputs に追加 |
|
| 114 | + buildInputs = old.buildInputs ++ [ final.pkgs.zlib ]; |
|
| 115 | + }); |
|
| 116 | +}) |
|
| 117 | +``` |
|
| 118 | +> **Note**: 現在、この不足ライブラリの特定と追加を自動化するツール(auto-rider)が開発中ですが、現時点では手動での対応が必要になることがあります。 |
|
| 119 | + |
|
| 120 | +--- |
|
| 121 | +この構成により、`flake.nix` の管理コストを最小限に抑えつつ、Python エコシステムの利便性と Nix の再現性を両立させた開発が可能になります。 |
|
| ... | ... | \ No newline at end of file |