uv : environnements et dépendances Python
Pour un dépôt ordinaire dont les dépendances existent sur les index Python avec des wheels adaptées :
uv + pyproject.toml + uv.lock + .venv local au dépôt
Cela ne rend pas Conda obsolète. uv gère surtout projets et versions Python, résolution et exécution. Conda peut aussi posséder bibliothèques natives, exécutables non Python et environnements multilangages. Un environnement doit avoir un propriétaire explicite ; pip, uv et Conda ne doivent pas le modifier tour à tour.
Choisir par frontière
| Condition | Départ | Raison |
|---|---|---|
| Application, CLI, script ou service avec wheels adaptées | uv | déclaration, verrou, environnement et commandes restent locaux |
| Extensions Python disponibles en wheel | environnement uv parallèle | installable ne signifie pas équivalent |
| CUDA, BLAS, GDAL, GEOS, TA-Lib ou outil natif fourni par Conda | garder Conda | uv ne remplace pas les dépendances système/multilangages |
| Automatisation de production liée à un environnement Conda | garder la référence et tester en parallèle | ne pas changer le chemin d’exécution en silence |
| sources, licences ou plateformes inconnues | reporter | établir inventaire et critères |
Une longue sortie de conda list n’est pas une liste de dépendances directes. Reconstituer l’intention depuis pyproject.toml, requirements, imports, entrées, tests et lancement.
Modèle du projet
pyproject.toml plage Python et dépendances directes voulues
uv.lock graphe exact résolu par uv
.python-version sélection Python optionnelle
.venv/ installation locale ignorée par Git
Versionner uv.lock sans l’éditer. Un verrou fixe une résolution, pas la confiance, la sûreté, la licence ou l’aptitude au déploiement.
Nouveau projet
uv python install 3.12
uv init example-app
cd example-app
uv python pin 3.12
uv add requests
uv add --dev pytest
uv sync
uv run python -m pytest
Pour des scripts non installés comme paquet :
[project]
name = "example-tool"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
[tool.uv]
package = false
package = false change l’installation, pas le besoin de tests, version et déclaration.
Dépôt existant
- Lire métadonnées, requirements, entrées, CI et lancement de production.
- Déclarer seulement les dépendances directement nécessaires ; ne pas copier l’environnement installé.
- Avec un
pyproject.toml, commencer paruv locketuv sync; migrer requirements selon le guide officiel. - Conserver l’ancien environnement et créer un
.venvparallèle. - Exécuter compilation, tests et charges représentatives en lecture seule.
- Pour le numérique, comparer résultats, backends, threads et performances, pas seulement les imports.
- Basculer CI, planificateurs, services et éditeurs en dernier, avec retour arrière.
Ne pas mêler migration, montée de Python, mise à jour générale et refactor : on ne saurait plus attribuer un échec.
Commandes
uv sync
uv run python script.py
uv run python -m unittest discover -s tests
uv pip check
uv add pandas
uv add --dev pytest
uv remove pandas
uv tree
uv lock --check
uv sync --locked
uv run --locked python -m pytest
uvx ruff check .
uv sync met normalement le verrou à jour si les métadonnées l’exigent. CI et release utilisent --locked pour échouer sur dérive. --frozen emploie le verrou sans vérifier sa cohérence : seulement si cette différence est voulue.
Préférer uv add/remove à l’installation manuelle. .venv est jetable ; pyproject.toml et uv.lock portent l’état.
Coexistence Conda
La coexistence se fait entre dépôts ou avec deux environnements indépendants, pas deux resolvers sur le même environnement. Un projet peut garder sa référence Conda et tester un shadow uv. Si Conda possède un runtime natif, documenter owner et commande complète. Un uv sync réussi n’autorise ni suppression ni bascule production.
Critères de bascule : tests, résultats représentatifs, contrôle des dépendances, installation cible, runtime et répétition du rollback.
| Symptôme | Vérifier |
|---|---|
| CI résout autrement | uv.lock versionné et --locked |
| mauvais Python | .python-version, requires-python, shell |
| comportement natif différent | wheel, BLAS/CUDA, système, threads |
| activation manuelle nécessaire | commande de lancement incomplète |
| verrou volumineux | normal : direct et transitif diffèrent |
| index privé refusé | secrets contrôlés, jamais dans docs/URL/Git |
Vie privée des notes publiques
Les exemples publics utilisent example-app, /path/to/repository et des services fictifs. Noms de dépôts, domaines internes, utilisateurs, chemins absolus, units, statut de migration, nombres de tests et dépendances non publiées restent dans des notes opérationnelles privées. Un guide public conserve les décisions et validations réutilisables, pas l’inventaire du poste de travail.