black : le formateur qui met fin aux débats de style en Python

black réécrit vos fichiers Python dans un style unique et non négociable. Ce qu'il décide, ce qu'il ne fera jamais, et quand ruff le rend inutile.
5 min de lecture
Believemy logo

Définition

Deux personnes écrivent la même fonction. L'une met des espaces autour du signe égal, l'autre non : le programme se comporte pareil, seule l'allure du fichier change. Les débats commencent là.

black existe pour les couper court. C'est un formateur de code Python : il relit un fichier, en reconstruit la structure, puis le réécrit selon un style unique. Il ne corrige aucun bug et ne change jamais ce que fait le programme, seulement la façon dont il est écrit.

Surtout, il ne se règle presque pas, et c'est voulu : un style dont on peut discuter redevient un sujet de discussion.

BASH
pip install black
black mon_fichier.py
black .

Installé avec pip, il travaille en une commande, directement dans le fichier. Son nom vient de la Ford T, disponible dans toutes les couleurs pourvu qu'elle soit noire, et il applique la PEP 8 pour clore la discussion sur le style, pas pour l'alimenter.


Le problème qu'il résout vraiment

Un style irrégulier ne fait planter aucun programme, et c'est pour cela qu'on le laisse s'installer. Le coût est ailleurs, à deux endroits.

En revue de code d'abord : quand rien n'impose la mise en forme, la moitié des remarques portent sur des espaces, et le relecteur survole ce qui comptait.

Dans l'historique ensuite : réindenter un fichier au passage produit quarante lignes modifiées pour un changement qui en concernait une, et le vrai changement disparaît dans le lot.

black efface les deux d'un coup, non parce que son style serait supérieur, mais parce qu'il est le même pour tout le monde et qu'il ne se négocie pas. Deux fichiers écrits de deux façons ressortent identiques, au caractère près.


Ce qu'il décide à votre place

Le premier passage sur un fichier existant surprend toujours. Voici une fonction écrite à la main, puis la même après black.

PYTHON
# Avant : espacement au hasard
def facture(client,lignes,remise = 0,devise='EUR'):
    total=sum( l['prix'] for l in lignes )
    return {'client':client,'total':total*(1-remise),'devise':devise}

# Après black : un seul style possible
def facture(client, lignes, remise=0, devise="EUR"):
    total = sum(l["prix"] for l in lignes)
    return {"client": client, "total": total * (1 - remise), "devise": devise}

Les guillemets simples sont passés en doubles, les espaces autour des opérateurs normalisés, ceux qui traînaient dans les parenthèses supprimés. Une ligne de plus de 88 caractères aurait été repliée, et aucune de ces décisions n'est un réglage que vous pourriez inverser.

Reste-t-il quelque chose sur quoi garder la main ? Un point, un seul. Une virgule laissée après le dernier élément d'une liste ou d'un appel de fonction vaut consigne, et black met alors un élément par ligne. Retirez-la, il rassemble tout dès qu'il y a la place.

Sans ce mécanisme en tête, l'outil paraît trancher au hasard : le même appel s'étale sur six lignes, puis tient sur une seule.

Bon à savoir

Là où la mise en forme porte du sens, une matrice alignée à la main par exemple, # fmt: off suspend black et # fmt: on le remet en marche.


Ce qu'il ne fait pas, et qui s'en charge

L'erreur la plus fréquente consiste à en attendre un contrôle qualité. black ne signale ni un import inutilisé, ni une variable jamais lue, ni un appel sur le mauvais type : il déplace du texte, il ne juge pas le code.

Il pose même une condition : devant une SyntaxError, il s'arrête sans rien réécrire, faute de pouvoir analyser la structure qu'il devrait reconstruire.

Chaque vérification dont il se dispense revient à un autre outil, et voici ce que chacun vous rend en retour.

BesoinOutilCe qu'il produit
Mise en formeblackUn fichier réécrit
Défauts et scoriesruffUne liste d'avertissements
Cohérence des typesmypyDes erreurs d'annotation de type
Comportement réelpytestDes tests qui passent ou non

La comparaison honnête ne se fait plus avec les anciens formateurs, mais avec ruff format, qui reproduit ce style à quelques cas près et bien plus vite. Si ruff est déjà là pour l'analyse, black fait double emploi.


L'erreur classique de l'adoption

Lancer black . sur un dépôt vivant réécrit trois cents fichiers d'un coup. Le programme fonctionne toujours, mais chaque ligne porte désormais votre nom et la date du jour : l'outil qui retrouve l'auteur d'une décision ne remonte plus qu'à vous.

Attention

Pire, un commit qui mêle un correctif et le reformatage du dossier entier est illisible : le relecteur cherche trois lignes utiles parmi mille, puis approuve sans rien vérifier.

La méthode propre tient en trois gestes. Formatez dans un commit qui ne contient que du formatage. Enregistrez son empreinte dans .git-blame-ignore-revs, que l'outil de suivi traversera comme s'il n'existait pas. Verrouillez enfin la suite en intégration continue, où la vérification refuse un fichier mal formaté.

BASH
black --check --diff .
git config blame.ignoreRevsFile .git-blame-ignore-revs


Questions fréquentes

Question

Peut-on modifier le style de black ?

Très peu, et c'est délibéré : la longueur de ligne se change, la normalisation des guillemets se désactive, tout le reste est figé. Ces réglages tiennent dans le pyproject.toml, le fichier qu'utilise déjà poetry. Chaque option de plus rouvrirait la discussion que black existe pour fermer.

Question

Faut-il installer black dans chaque projet ?

Oui, dans l'environnement virtuel du projet et avec une version fixée. Le style évolue légèrement d'une version majeure à l'autre : deux machines mal accordées reformatent le fichier chacune à leur façon, et la guerre des diffs reprend.

Question

black peut-il casser mon code ?

C'est très improbable : il compare la structure du fichier réécrit à celle de l'original et refuse le résultat au moindre écart. Une nuance existe pourtant : il nettoie les espaces de fin de ligne dans une docstring, ce qui peut faire échouer un test qui compare cette chaîne au caractère près.

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.