ruff : l'outil qui relit votre code Python en une fraction de seconde

ruff relit votre code Python sans l'exécuter et signale imports morts, variables inutiles et écarts de style, en une fraction de seconde.
5 min de lecture
Believemy logo

Définition

Un projet Python grossit vite, et de petits défauts s'accumulent sans que personne les remarque : un import qui ne sert plus depuis un refactor, une variable jamais relue, une ligne qui s'écarte de ce que la PEP 8 recommande. Rien de cela ne fait planter le programme, mais le fichier finit par devenir difficile à relire pour quelqu'un d'autre que son auteur.

C'est ce que ruff est censé rattraper : il relit le code sans l'exécuter et signale ce qui cloche. Ce travail porte un nom, le lint, et il existait bien avant ruff. La nouveauté tient à deux choses : écrit en Rust, il traverse un projet en une fraction de seconde là où ses prédécesseurs demandaient plusieurs minutes, et il regroupe en un seul binaire ce qui demandait quatre ou cinq programmes.

Deux commandes suffisent, depuis la racine du projet.

BASH
pip install ruff
ruff check .

La commande parcourt tous les fichiers du dossier et affiche une ligne par problème, avec le fichier, la position et un code de règle. Rien n'est modifié tant que vous ne le demandez pas. L'installation passe par pip, dans l'environnement virtuel du projet.


Ce qu'il voit, et ce qu'il ne verra jamais

Un exemple vaut mieux qu'une explication abstraite. Voici un fichier qui tourne sans planter, et qui contient pourtant trois défauts que ruff va repérer.

PYTHON
import os
import json

def charger(chemin):
    donnees = json.load(open(chemin))
    total = 0
    return donnees

ruff relève l'import os inutile (règle F401), la variable total calculée pour personne (F841), et le fichier jamais refermé : trois défauts invisibles à l'exécution, qui coûtent en lisibilité et en ressources laissées ouvertes.

Une question vient alors naturellement : ruff attrape-t-il tout ce qui peut aller mal ? Non : son analyse est statique, elle lit le texte du programme sans jamais l'exécuter. Le tableau sépare ce qu'il peut repérer de ce qui lui échappe.

Il le repèreIl ne peut pas le savoir
Un import inutilisé ou écrit deux foisQu'une liste sera vide et lèvera une IndexError
Un nom employé avant d'exister, futur NameErrorQu'une clé manquera dans un dictionnaire au moment de la lire
Une comparaison écrite à l'enversQue votre calcul de remise applique le mauvais pourcentage

Cette limite découle de ce que ruff est censé faire vite. Elle explique pourquoi il ne remplace ni pytest, qui vérifie ce que le code produit une fois lancé, ni mypy, qui confronte les annotation de type entre elles. Ces trois outils répondent à des questions différentes.


Le formateur, face à black

Repérer les défauts n'est que la moitié du travail de ruff. Sous une commande distincte, ruff format, il réécrit la mise en forme, sans toucher au sens du programme. Ce terrain est celui de black, dont il reprend le style presque au caractère près.

Faut-il basculer, pour qui utilise déjà black ? Sur un projet existant, ruff format ne change pas l'apparence du code, seulement la vitesse et le nombre d'outils à maintenir. Sur un projet neuf, ruff seul évite deux réglages à synchroniser. Sur une équipe attachée à une option précise, un essai sur une branche s'impose avant de trancher.

Retenez la distinction : ruff check répond à « qu'est-ce qui coûte cher ? », ruff format à « à quoi doit ressembler le code ? ». Une indentation irrégulière n'est pas un bug, un import mort ne se règle pas en déplaçant des espaces.


Le réglage qui décide de tout

Une erreur classique consiste à activer d'un coup toutes les règles disponibles, puis à lancer l'outil sur un projet déjà en place. Le terminal renvoie des milliers d'avertissements, en majorité des préférences stylistiques que personne n'a réclamées, et l'outil finit désactivé avant la fin de la semaine.

La marche qui fonctionne : garder le jeu de règles par défaut, qui ne signale que les vrais problèmes, puis ajouter une famille à la fois, en corrigeant ce qu'elle remonte.

FamilleCe qu'elle apporte
FLes défauts réels : imports morts, variables inutiles, noms inconnus
ELes écarts de mise en forme hérités de la norme de style officielle
ILe tri et le regroupement des imports en tête de fichier
UPLes tournures devenues obsolètes sur les versions récentes de Python

Le réglage vit dans pyproject.toml, sous [tool.ruff.lint]. La configuration devient commune à toute l'équipe et à l'intégration continue. Un fichier versionné vaut toujours mieux qu'une option tapée à la main, que la moitié des postes oublieront.


Questions fréquentes

Question

Faut-il garder black si on utilise déjà ruff ?

Non, ce n'est plus nécessaire : ruff embarque son propre formateur, et faire tourner les deux revient à réécrire le même fichier deux fois pour un résultat presque identique. Garder l'ancien outil ne se justifie que si la configuration s'appuie sur une option que ruff n'expose pas encore.

Question

Comment réagir face aux centaines d'erreurs affichées au premier passage ?

Surtout pas en les corrigeant toutes le même jour : un commit qui touche cinq cents fichiers rend l'historique illisible et noie les vraies modifications. La méthode qui fonctionne consiste à lancer ruff check --fix, qui règle la part mécanique, puis à restreindre les règles à ce que l'équipe est prête à corriger maintenant.

Question

La correction automatique peut-elle casser du code qui fonctionnait ?

Les corrections par défaut sont dites sûres : elles ne changent jamais le comportement du programme. D'autres, marquées comme risquées, ne s'appliquent qu'avec une option supplémentaire, et peuvent retirer un commentaire ou déplacer une valeur par défaut. Ne jamais lancer une correction automatique sur un dossier de travail non enregistré, pour pouvoir revenir en arrière d'un geste.

Termes connexes

Découvrez notre glossaire Python

Parcourez les termes et définitions les plus couramment utilisés dans le domaine du développement avec Python.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.