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