14 points par GN⁺ 2025-07-22 | 7 commentaires | Partager sur WhatsApp
  • Avec uv, la gestion des dépendances est automatisée lors de l’exécution de scripts Python
  • Sans gestion d’environnement virtuel séparée, un environnement est automatiquement créé et maintenu pour chaque script
  • Les paquets nécessaires peuvent être déclarés de différentes façons, comme via des métadonnées inline ou des options en ligne de commande
  • La version de Python et la gestion des paquets peuvent aussi être déclarées au niveau du script et ajustées automatiquement
  • Les fichiers de lock et les options de contrainte de version des dépendances améliorent la reproductibilité et la maintenabilité

Aperçu

  • uv est un outil qui gère automatiquement les dépendances de paquets requises par un script Python lors de son exécution
  • L’utilisateur n’a pas besoin de créer lui-même des environnements virtuels ni d’installer des paquets manuellement
  • Il fournit plusieurs options d’exécution, l’usage de métadonnées inline, différentes façons de déclarer les dépendances et divers mécanismes de contrôle

Environnement Python et rôle de uv

  • Python dispose d’un environnement propre pour chaque installation
  • En général, il est recommandé de créer et gérer des environnements virtuels
  • uv gère automatiquement les environnements virtuels et traite les dépendances de manière déclarative
  • Un script simple peut être exécuté immédiatement avec uv run example.py
  • Si seul la bibliothèque standard est utilisée, cela fonctionne sans configuration supplémentaire

Passage d’arguments et modes d’entrée

  • Il est possible de transmettre des arguments en ligne de commande au script
  • L’outil prend aussi en charge l’exécution directe du code du script depuis l’entrée standard, ainsi que la fonctionnalité here-document

Environnement de projet et option --no-project

  • Si un script est exécuté dans un dossier de projet (par exemple, là où se trouve pyproject.toml), les dépendances du projet sont également installées
  • Si ce n’est pas souhaité, on peut ignorer l’environnement du projet en plaçant le flag --no-project avant le nom du script

Déclaration et gestion des dépendances du script

  • Lorsqu’un paquet externe est nécessaire, il est possible d’indiquer la dépendance à l’exécution avec l’option --with
  • Les contraintes sur des versions spécifiques sont prises en charge, et plusieurs dépendances peuvent être indiquées en répétant l’option
  • Il est possible d’ajouter des dépendances supplémentaires dans l’environnement du projet, et de contrôler cela avec --no-project si besoin

Inline Script Metadata (méthode PEP 723)

  • Python prend désormais en charge un format standard permettant de déclarer directement dans le script les dépendances ou la version de Python
  • uv init --script permet de créer facilement un script contenant des métadonnées inline
  • uv add --script permet d’ajouter et de gérer en format TOML les dépendances nécessaires au script
  • En présence de métadonnées inline, les dépendances du projet sont ignorées et seules celles du script sont appliquées

Déclaration et gestion de la version de Python

  • Il est possible de définir la version de Python souhaitée dans le script ou au moment de l’exécution
  • Si la version indiquée n’est pas disponible, elle est automatiquement téléchargée et configurée

Écriture de scripts directement exécutables avec un shebang

  • En utilisant un shebang (#!...), il est possible de créer un exécutable direct avec la méthode uv run --script
  • Dans ce cas également, la déclaration des dépendances et la version de Python peuvent être définies en tête du script

Prise en charge des index de paquets et de l’authentification

  • L’option --index permet d’utiliser un index de paquets personnalisé
  • Les informations d’index peuvent aussi être incluses dans les métadonnées
  • En cas d’authentification requise, il est possible de se référer à une documentation distincte

Verrouillage des dépendances et amélioration de la reproductibilité

  • uv lock --script permet de créer et gérer un fichier de lock au niveau du script
  • Lors des exécutions suivantes ou de l’ajout de dépendances, le fichier de lock est réutilisé et mis à jour si nécessaire
  • L’option exclude-newer (exclure les versions publiées après une date donnée) est fournie pour la reproductibilité des versions
  • La date est spécifiée au format horodaté RFC 3339

Souplesse des versions de Python

  • À chaque exécution, il est possible de choisir n’importe quelle version de Python via une option en ligne de commande
  • Exemple : uv run --python 3.10 example.py

Prise en charge de Windows

  • Les scripts portant l’extension .pyw sont exécutés avec pythonw sous Windows
  • Les scripts à interface graphique peuvent eux aussi être exécutés avec leurs dépendances

Documentation de référence

  • Pour un usage plus détaillé des commandes, il est possible de consulter la documentation de référence de la CLI ainsi que les guides d’exécution et d’installation de l’outil

Conclusion

  • uv est un outil qui gère automatiquement et simplement l’environnement d’exécution, les dépendances, les versions, les index de paquets et la reproductibilité des scripts Python, améliorant à la fois la productivité et la fiabilité

7 commentaires

 
ihabis02 2025-07-24

Je suis moi aussi passé de pip à uv, et franchement rien que pour la vitesse, ça vaut le coup de changer.

 
idunno 2025-07-23

Le sujet revient souvent, alors je l’ai essayé pour la première fois hier… c’est vraiment rapide. Wow…

 
ytuniverse 2025-07-23

J’ai l’impression avoir déjà vu plus de cinq posts sur uv ici ;; ;

 
pmc7777 2025-07-23

Même en laissant de côté les autres fonctionnalités, la seule vitesse suffit largement à justifier son utilisation.
Si on me demandait de réutiliser pip, j’en serais absolument incapable.

J’ai remplacé la gestion des paquets système de conda par flake.nix, mais en dehors des projets collaboratifs ou des projets existants maintenus avec conda+pip, j’utiliserai probablement uv+nix à l’avenir pour mes usages personnels.

 
ndrgrd 2025-07-22

J’ai récemment remplacé la plupart de mes exécutions Python par uv, et c’est vraiment rapide.
Il existe bien quelques fonctionnalités avancées qui ne sont pas parfaitement compatibles, mais dans la plupart des cas, le comportement est presque identique.

 
GN⁺ 2025-07-22
Commentaires sur Hacker News
  • J’ai constaté à quel point la fonctionnalité de « déclaration des dépendances du script » est utile
    Comme présenté dans la documentation officielle, on peut indiquer les dépendances en commentaire tout en haut du code Python, comme ceci

    # /// script
    # dependencies = [
    #  "requests<3",
    #  "rich",
    # ]
    # ///
    import requests, rich
    # ... script
    

    Si l’on enregistre ce fichier sous script.py puis qu’on l’exécute avec uv run script.py, les dépendances déclarées sont installées comme par magie dans un environnement virtuel temporaire et le script peut être lancé immédiatement
    Il s’agit d’une implémentation de la PEP 723 de Python, et Claude 4 connaît aussi cette astuce, donc si on lui demande d’écrire « un script Python avec des dépendances inline », il le fait correctement
    On peut par exemple lui demander de générer du code qui télécharge un gros fichier avec httpx et click tout en affichant une barre de progression
    Avant Claude 4, ce genre de fonctionnalité nécessitait un projet sur mesure et des consignes séparées, mais ce n’est plus le cas
    On peut aussi consulter ce cas d’usage détaillé

    • Le mode shebang est lui aussi vraiment pratique
      En ajoutant le shebang suivant à la première ligne du script, on peut l’exécuter comme ./script.sh

      #!/usr/bin/env -S uv run --script
      # /// script
      # dependencies = [
      #  "requests<3",
      #  "rich",
      # ]
      # ///
      import requests, rich
      # ... script
      
    • J’aimerais que le format soit identique à celui d’un fichier requirements
      Cela permettrait, pour les utilisateurs qui n’ont pas uv, d’ajouter un simple commentaire avec une commande en une ligne pour installer la même chose avec pip
      Une approche du genre pip install -r <(head myscript.py) semblerait possible

    • En pratique, la PEP 723 est désormais prise en charge non seulement par uv, qui attire beaucoup l’attention en ce moment, mais aussi par pipx et hatch
      Et le support figure aussi sur la feuille de route de pip-tools, entre autres
      (voir ce ticket)

    • La première fois, j’ai cru que c’était un emoji cœur à côté de requests

    • Je trouve cette approche vraiment élégante
      Mais j’aimerais qu’un jour cela soit adopté comme une syntaxe intégrée au langage plutôt que comme des commentaires magiques
      Les commentaires donnent un aspect un peu brouillon
      Bien sûr, je comprends que du point de vue des outils, les commentaires magiques sont plus simples à parser et qu’il y a aussi des questions structurelles, comme le fait que le cœur de Python ne maîtrise pas tant que ça le packaging, mais j’aimerais quand même voir apparaître une syntaxe native un jour

  • Je partage complètement cette approche
    C’est dommage que, même si Python n’impose pas un fichier requirements.txt, on se retrouve souvent avec des choses qui cassent quand on néglige sa gestion
    Tweet associé

  • Je voudrais partager un piège rencontré avec cette méthode
    Je l’ai utilisée pour un script qui redémarre le routeur quand Internet tombe, mais comme l’installation des dépendances dépend de la connexion réseau, si le réseau ne fonctionne plus le script lui-même devient inutilisable
    Je m’en suis rendu compte à temps et j’ai résolu le problème en préinstallant les dépendances, mais ne faites pas la même erreur que moi et évitez de l’utiliser dans un vrai environnement air-gapped (complètement isolé du réseau)
    Même avec le cache uv, on peut avoir un cache miss

    • Avec l’option uv run --offline, on peut utiliser les dépendances en cache sans vérifier s’il existe de nouvelles versions
      La même chose fonctionne aussi avec uvx (uvx --offline ...)

    • Si l’on a besoin d’utiliser des dépendances ou un venv, il me semble qu’il faut au moins une première exécution avec une connexion Internet pour pouvoir ensuite l’utiliser hors ligne

  • J’ai l’impression qu’en ce moment, dans l’écosystème Python, de plus en plus de fonctionnalités commencent à bien s’emboîter
    Avec la combinaison de Marimo et des dépendances de script uv, je commence à créer des outils de reporting et de diagnostic reproductibles, faciles à utiliser par d’autres équipes

  • C’est la fonctionnalité de uv que je préfère, au point de m’avoir fait passer à uv
    Plusieurs scripts de git-hooks ont chacun leurs propres dépendances, et je ne voulais pas les installer dans le venv principal
    Il suffisait d’ajouter #!/usr/bin/env -S uv run --script --python 3.13, puis de dire aux devs de faire brew install uv, et ils pouvaient les utiliser directement dans le script sans créer de venv séparé

    • Je me demande si quelqu’un sait pourquoi le flag -S est nécessaire
      Sur mon environnement BSD, /usr/bin/env -S uv run --python 3.11 python et /usr/bin/env uv run --python 3.11 python lancent tous deux le shell Python, donc j’ai l’impression que le résultat est identique
      Même après avoir lu la page de manuel de env, je n’ai pas trouvé d’explication claire, donc si quelqu’un a une info utile, je suis preneur
      (Ici, -S sert à séparer les arguments sur les espaces)

    • Grâce à uv, une grande migration Python qui devait initialement se faire vers golang a pu être réduite
      En particulier, les petits travaux sous forme de scripts n’ont plus besoin d’être déplacés

    • Je suis convaincu que c’est une véritable fonctionnalité « killer »

  • Si l’une des dépendances est Pytorch, cette approche peut être un peu limitée
    Uv offre bien une prise en charge intégrée pour Pytorch, mais rien dans l’en-tête du script ne permet vraiment de choisir clairement l’index de wheels le plus adapté (CPU, CUDA, ROCm, etc.)

  • J’aimerais que VS Code puisse reconnaître facilement les venv créés automatiquement par uv
    Pour l’instant, l’extension Python souligne tous les imports tiers en rouge
    En solution temporaire, je vais chercher manuellement le chemin du venv dans le répertoire de cache de uv pour l’enregistrer, mais si le venv est recréé régulièrement, il faut recommencer à chaque fois, ce qui est pénible

    • On peut trouver le chemin de l’environnement avec la commande uv python find --script "${filePath}"
      Je développe une extension pour que VS Code détecte automatiquement cela et active le bon interpréteur
  • J’adore tellement cette fonctionnalité de UV
    On peut même lancer un notebook jupyter en une seule ligne, sans installation séparée, comme ceci

    uv run --with jupyter jupyter notebook
    

    Tout est installé dans un environnement virtuel temporaire, puis nettoyé ensuite
    Si on l’exécute dans un projet, ses dépendances sont aussi détectées automatiquement

    • Cela dit, ce n’est pas totalement « proprement » nettoyé, car le dossier de cache de uv peut continuer à grossir

    • Moi aussi, j’utilise souvent des commandes du type uv run --with ipython --with boto3 ipython, et cela me fait vraiment gagner beaucoup de temps

  • J’ai récemment remarqué un petit souci avec uv run
    Si l’on exécute un script depuis l’extérieur du dossier du projet, il cherche pyproject.toml dans le répertoire de travail courant plutôt qu’à l’emplacement réel du fichier script
    Du coup, un script dont les dépendances sont stockées dans pyproject.toml peut ne pas fonctionner correctement si on le lance depuis l’extérieur avec une commande comme uv run path/to/my/script.py
    On peut contourner cela soit en utilisant toujours des dépendances inline, soit en passant l’argument --project, mais cela oblige à saisir deux fois le chemin du script, ce qui est peu pratique
    uv reste excellent, mais cette petite particularité est assez agaçante

  • J’utilisais déjà avec satisfaction le shebang spécifique à uv et les dépendances définies dans le script
    J’ai été encore plus impressionné en découvrant qu’on peut aussi générer un fichier lock dédié à un script unique avec uv lock --script example.py
    Après plus de 20 ans de packaging Python, je suis surpris qu’une expérience aussi naturelle n’apparaisse que maintenant

    • Je serais curieux de connaître des cas d’usage pour la génération d’un lock dédié à un seul script
      Dans notre organisation, on scanne aussi les dépendances des lockfiles avec trivy fs uv.lock afin d’éviter d’exécuter du code contenant des CVE connues