Relecture du fichier python

This commit is contained in:
Gregory Trullemans 2023-04-22 15:14:11 +02:00
parent 63f2cf23f4
commit 8d7a61aa11
1 changed files with 276 additions and 359 deletions

View File

@ -17,15 +17,12 @@ Chacune d'entre elles doit être approuvée par le \href{http://fr.wikipedia.org
Le langage Python utilise un typage dynamique appelé \href{https://fr.wikipedia.org/wiki/Duck_typing}{\textbf{duck typing}} :
\begin{quote}
"\emph{When I see a bird that quacks like a duck, walks like a duck, has
feathers and webbed feet and associates with ducks --- I'm certainly
going to assume that he is a duck}"
"\emph{When I see a bird that quacks like a duck, walks like a duck, has feathers and webbed feet and associates with ducks --- I'm certainly going to assume that he is a duck.}"
-- Source: \href{http://en.wikipedia.org/wiki/Duck_test}{Wikipedia}.
\end{quote}
En fonction de votre niveau d'apprentissage du langage, plusieurs
ressources pourraient vous aider:
En fonction de votre niveau d'apprentissage du langage, plusieurs ressources pourraient vous aider :
\begin{itemize}
\item
@ -34,23 +31,17 @@ ressources pourraient vous aider:
with Python} \cite{boring_stuff}, aka. \emph{Practical
Programming for Total Beginners}
\item
\textbf{Pour un (gros) niveau au dessus} et pour un état de l'art du langage, nous ne pouvons que vous recommander le livre Expert Python Programming \cite{expert_python}, qui aborde énormément d'aspects du langage en détails (mais pas toujours en profondeur): les différents types d'interpréteurs, les éléments de langage avancés, différents outils de productivité, métaprogrammation, optimisation de code, programmation orientée évènements, multithreading et concurrence, tests, ...
\textbf{Pour un (gros) niveau au dessus} et pour un état de l'art du langage, nous ne pouvons que vous recommander le livre Expert Python Programming \cite{expert_python}, qui aborde énormément d'aspects du langage en détails (mais pas toujours en profondeur) : les différents types d'interpréteurs, les éléments de langage avancés, différents outils de productivité, métaprogrammation, optimisation de code, programmation orientée évènements, multithreading et concurrence, tests, \ldots~
A ce jour, c'est le concentré de sujets liés au langage le plus intéressant qui ait pu arriver entre nos mains.
\end{itemize}
En parallèle, si vous avez besoin d'un aide-mémoire ou d'une liste
exhaustive des types et structures de données du langage, référez-vous
au lien suivant:
\href{https://gto76.github.io/python-cheatsheet/}{Python Cheat Sheet}.
En parallèle, si vous avez besoin d'un aide-mémoire ou d'une liste exhaustive des types et structures de données du langage, référez-vous au lien suivant : \href{https://gto76.github.io/python-cheatsheet/}{Python Cheat Sheet}.
\section{Protocoles de langage}
Le modèle de données du langage spécifie un ensemble de méthodes qui
peuvent être surchargées. Ces méthodes suivent une convention de nommage
et leur nom est toujours encadré par un double tiret souligné; d'où leur
nom de "\emph{dunder methods}\index{dunder}" ou "\emph{double-underscore methods}". La
méthode la plus couramment utilisée est la méthode \texttt{init()}, qui
permet de surcharger l'initialisation d'une instance de classe.
Le modèle de données du langage spécifie un ensemble de méthodes qui peuvent être surchargées.
Ces méthodes suivent une convention de nommage et leur nom est toujours encadré par un double tiret souligné ; d'où leur nom de "\emph{dunder methods}\index{dunder}" ou "\emph{double-underscore methods}".
La méthode la plus couramment utilisée est la méthode \texttt{init()}, qui permet de surcharger l'initialisation d'une instance de classe.
\begin{listing}[!ht]
\begin{minted}{python}
@ -83,7 +74,7 @@ Les points principaux à présenter ci-dessus:
\item item()
\item getitem() - pour utiliser les []
\item len() - pour connaître la longueur d'un objet
\item ...
\item \ldots
\end{enumerate}
Le langage autorise nativement plus d'une cinquantaine d'opérateurs différents :
@ -94,7 +85,7 @@ Le langage autorise nativement plus d'une cinquantaine d'opérateurs différents
\item Opérateurs de comparaisons
\item Opérateurs d'identité
\item Opérateurs de comparaison bit à bit
\item ...
\item \ldots
\end{enumerate}
Par exemple, la méthode \texttt{add()} est responsable de l'implémentation de l'opérateur \texttt{+}, la méthode \texttt{sub()} s'occupe de la soustraction ()\texttt{}), tandis que \texttt{mul()} gère l'opérateur \texttt{*}.
@ -156,11 +147,11 @@ Nous pouvons donc utiliser ces mêmes \textbf{dunder methods} (\textbf{double-un
\section{Guide de style}
La première PEP qui va nous intéresser est la PEP8.
Elle spécifie comment du code Python doit être organisé ou formaté, quelles sont les conventions pour l'indentation, le nommage des variables et des classes, ...
Elle spécifie comment du code Python doit être organisé ou formaté, quelles sont les conventions pour l'indentation, le nommage des variables et des classes, \ldots
En bref, elle décrit comment écrire du code proprement, afin que d'autres développeurs puissent le reprendre facilement, ou simplement que votre base de code ne dérive lentement vers un seuil de non-maintenabilité.
Dans cet objectif, un outil existe et listera l'ensemble des conventions qui ne sont pas correctement suivies dans votre projet: flake8. Pour l'installer, passez par pip.
Lancez ensuite la commande \texttt{flake8} suivie du chemin à analyser (\texttt{.}, le nom d'un répertoire, le nom d'un fichier \texttt{.py}, ...).
Lancez ensuite la commande \texttt{flake8} suivie du chemin à analyser (\texttt{.}, le nom d'un répertoire, le nom d'un fichier \texttt{.py}, \ldots).
Si vous souhaitez uniquement avoir le nombre d'erreur de chaque type, saisissez les options \texttt{-\/-statistics\ -qq} - l'attribut \texttt{-qq} permettant simplement d'ignorer toute sortie console autre que les statistiques demandées).
\begin{listing}[!ht]
@ -196,12 +187,12 @@ Toute fonction dans la complexité est supérieure à cette valeur sera considé
Python étant un langage interprété fortement typé, il est plus que conseillé, au même titre que les tests unitaires que nous verrons plus bas, de documenter son code.
Ceci impose une certaine rigueur, tout en améliorant énormément la qualité, la compréhension et la reprise du code par une tierce personne.
Ceci implique aussi de \textbf{tout} documenter: les modules, les paquets, les classes, les fonctions, méthodes, ... ce qui peut aller à contrecourant d'autres pratiques \cite{clean_code}{53-74} ; il y a donc une juste mesure à prendre entre "tout documenter" et "tout bien documenter":
Ceci implique aussi de \textbf{tout} documenter: les modules, les paquets, les classes, les fonctions, méthodes, \ldots~ ce qui peut aller à contrecourant d'autres pratiques \cite{clean_code}{53-74} ; il y a donc une juste mesure à prendre entre "tout documenter" et "tout bien documenter":
\begin{itemize}
\item
Inutile d'ajouter des watermarks, auteurs, ...
Inutile d'ajouter des watermarks, auteurs, \ldots
Git ou tout VCS s'en sortira très bien et sera beaucoup plus efficace que n'importe quelle chaîne de caractères que vous pourriez indiquer et qui sera fausse dans six mois,
\item
Inutile de décrire quelque chose qui est évident; documenter la méthode \mintinline{python}{get_age()} d'une personne n'aura pas beaucoup d'intérêt
@ -219,7 +210,7 @@ Il existe plusieurs types de balisages reconnus/approuvés:
\item Google Style (parfois connue sous l'intitulé \texttt{Napoleon})
\end{enumerate}
... mais tout système de balisage peut être reconnu, sous réseve de respecter la structure de la PEP257.
\ldots~ mais tout système de balisage peut être reconnu, sous réseve de respecter la structure de la PEP257.
\subsection{PEP 257}
@ -234,7 +225,7 @@ Elle contient des conventions, pas des règles ou
-- Tim Peters on comp.lang.python, 2001-06-16
\end{quote}
Ainsi, les conventions sont décrites; chaque format propose ensuite son propre balisage (ReStructuredText, Numpy, Napoleon, ...).
Ainsi, les conventions sont décrites ; chaque format propose ensuite son propre balisage (ReStructuredText, Numpy, Napoleon, \ldots).
A priori, vous pourriez tout à fait utiliser le vôtre, sous réserve que les conventions de la PEP-257 soient respectées.
\subsection{RestructuredText}
@ -294,26 +285,14 @@ C'est-à-dire:
\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\item
Une courte ligne d'introduction, descriptive, indiquant ce que la
fonction ou la méthode réalise. Attention, la documentation ne doit
pas indiquer \emph{comment} la fonction/méthode est implémentée, mais
ce qu'elle fait concrètement (et succintement).
\item
Une ligne vide
\item
Une description plus complète et plus verbeuse, si vous le jugez
nécessaire
\item
Une ligne vide
\item
La description des arguments et paramètres, des valeurs de retour, des
exemples et les exceptions qui peuvent être levées.
Une courte ligne d'introduction, descriptive, indiquant ce que la fonction ou la méthode réalise. Attention, la documentation ne doit pas indiquer \emph{comment} la fonction/méthode est implémentée, mais ce qu'elle fait concrètement (et succintement).
\item Une ligne vide
\item Une description plus complète et plus verbeuse, si vous le jugez nécessaire
\item Une ligne vide
\item La description des arguments et paramètres, des valeurs de retour, des exemples et les exceptions qui peuvent être levées.
\end{enumerate}
Un exemple (encore) plus complet peut être trouvé
\href{https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html\#example-google}{dans
le dépôt sphinxcontrib-napoleon}. Et ici, nous tombons peut-être dans
l'excès de zèle:
Un exemple (encore) plus complet peut être trouvé \href{https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html\#example-google}{dans le dépôt sphinxcontrib-napoleon}. Et ici, nous tombons peut-être dans l'excès de zèle :
\begin{figure}[!ht]
\centering
@ -321,10 +300,7 @@ l'excès de zèle:
\caption{\url{https://xkcd.com/353/}}
\end{figure}
Pour ceux que cela pourrait intéresser, il existe
\href{https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring}{une
extension pour Codium}, comme nous le verrons juste après, qui permet de
générer automatiquement le squelette de documentation d'un bloc de code:
Pour ceux que cela pourrait intéresser, il existe \href{https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring}{une extension pour Codium}, comme nous le verrons juste après, qui permet de générer automatiquement le squelette de documentation d'un bloc de code : %(TODO : il manque pas un truc ici ??)
Nous le verrons plus loin, Django permet de rendre la documentation immédiatement accessible depuis l'interface d'administration.
Toute information pertinente peut donc lier le code à un cas d'utilisation concret, et rien n'est jamais réellement perdu.
@ -336,36 +312,19 @@ Il existe plusieurs niveaux de \emph{linters}:
\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\item
Le premier niveau concerne
\href{https://pypi.org/project/pycodestyle/}{pycodestyle}
(anciennement, \texttt{pep8} justement\ldots\hspace{0pt}), qui analyse
votre code à la recherche d'erreurs de convention.
Le premier niveau concerne \href{https://pypi.org/project/pycodestyle/}{pycodestyle} (anciennement, \texttt{pep8} justement\ldots\hspace{0pt}), qui analyse votre code à la recherche d'erreurs de convention.
\item
Le deuxième niveau concerne
\href{https://pypi.org/project/pyflakes/}{pyflakes}. Pyflakes est un
\emph{simple} \footnote{Ce n'est pas moi qui le dit, c'est la doc du
projet} programme qui recherchera des erreurs parmi vos fichiers
Python.
Le deuxième niveau concerne \href{https://pypi.org/project/pyflakes/}{pyflakes}. Pyflakes est un \emph{simple} \footnote{Ce n'est pas moi qui le dit, c'est la doc du projet} programme qui recherchera des erreurs parmi vos fichiers Python.
\item
Le troisième niveau est
\href{https://pypi.org/project/flake8/}{Flake8}, qui regroupe les deux
premiers niveaux, en plus d'y ajouter flexibilité, extensions et une
analyse de complexité de McCabe.
Le troisième niveau est \href{https://pypi.org/project/flake8/}{Flake8}, qui regroupe les deux premiers niveaux, en plus d'y ajouter flexibilité, extensions et une analyse de complexité de McCabe.
\item
Le quatrième niveau \footnote{Oui, en Python, il n'y a que quatre
cercles à l'Enfer} est \href{https://pylint.org/}{PyLint}.
Le quatrième niveau \footnote{Oui, en Python, il n'y a que quatre cercles à l'Enfer} est \href{https://pylint.org/}{PyLint}.
\end{enumerate}
PyLint est le meilleur ami de votre \emph{moi} futur, un peu comme quand
vous prenez le temps de faire la vaisselle pour ne pas avoir à la faire
le lendemain: il rendra votre code soyeux et brillant, en posant des
affirmations spécifiques. A vous de les traiter en corrigeant le code ou
en apposant un \emph{tag} indiquant que vous avez pris connaissance de
la remarque, que vous en avez tenu compte, et que vous choisissez malgré
tout de faire autrement.
PyLint est le meilleur ami de votre \emph{moi} futur, un peu comme quand vous prenez le temps de faire la vaisselle pour ne pas avoir à la faire le lendemain : il rendra votre code soyeux et brillant, en posant des affirmations spécifiques.
A vous de les traiter en corrigeant le code ou en apposant un \emph{tag} indiquant que vous avez pris connaissance de la remarque, que vous en avez tenu compte, et que vous choisissez malgré tout de faire autrement.
Pour vous donner une idée, voici ce que cela pourrait donner avec un
code pas très propre et qui ne sert à rien:
Pour vous donner une idée, voici ce que cela pourrait donner avec un code pas très propre et qui ne sert à rien :
\begin{listing}[!ht]
\begin{minted}{python}
@ -405,21 +364,12 @@ Nous trouvons des erreurs:
\begin{itemize}
\item
de \textbf{conventions}: le nombre de lignes qui séparent deux
fonctions, le nombre d'espace après un opérateur, une ligne vide à la
fin du fichier, \ldots\hspace{0pt} Ces \emph{erreurs} n'en sont pas
vraiment, elles indiquent juste de potentiels problèmes de
communication si le code devait être lu ou compris par une autre
personne.
de \textbf{conventions} : le nombre de lignes qui séparent deux fonctions, le nombre d'espace après un opérateur, une ligne vide à la fin du fichier, \ldots\hspace{0pt} Ces \emph{erreurs} n'en sont pas vraiment, elles indiquent juste de potentiels problèmes de communication si le code devait être lu ou compris par une autre personne.
\item
de \textbf{définition}: une variable assignée mais pas utilisée ou une
lexème non trouvé. Cette dernière information indique clairement un
bug potentiel. Ne pas en tenir compte nuira sans doute à la santé de
votre code (et risque de vous réveiller à cinq heures du mat', quand
votre application se prendra méchamment les pieds dans le tapis).
de \textbf{définition} : une variable assignée mais pas utilisée ou une lexème non trouvé. Cette dernière information indique clairement un bug potentiel. Ne pas en tenir compte nuira sans doute à la santé de votre code (et risque de vous réveiller à cinq heures du mat', quand votre application se prendra méchamment les pieds dans le tapis).
\end{itemize}
L'étape d'après consiste à invoquer pylint. Lui, il est directement moins conciliant:
L'étape d'après consiste à invoquer pylint. Lui, il est directement moins conciliantc:
\begin{verbatim}
$ pylint test.py
@ -448,14 +398,10 @@ En gros, j'ai programmé comme une grosse bouse anémique (et oui: le score d'é
En vrac, nous trouvons des problèmes liés:
\begin{itemize}
\item
au nommage (C0103) et à la mise en forme (C0305, C0326, W0105)
\item
à des variables non définies (E0602)
\item
de la documentation manquante (C0114, C0116)
\item
de la redéfinition de variables (W0621).
\item au nommage (C0103) et à la mise en forme (C0305, C0326, W0105)
\item à des variables non définies (E0602)
\item de la documentation manquante (C0114, C0116)
\item de la redéfinition de variables (W0621).
\end{itemize}
Pour reprendre la
@ -463,27 +409,22 @@ Pour reprendre la
chaque code possède sa signification:
\begin{itemize}
\item
\textbf{C}, pour toutes les vérifications liées aux conventions (nommage et mises en forme, que l'on a vues ci-dessus)
\item
\textbf{R}, pour des propositions de refactoring
\item
\textbf{W}, pour tout ce qui est en lien avec des avertissements
\item
\textbf{E} pour les erreurs ou des bugs probablement présents dans le code
\item
\textbf{F} pour les erreurs internes au fonctionnement de pylint, qui font que le traitement n'a pas pu aboutir.
\item \textbf{C}, pour toutes les vérifications liées aux conventions (nommage et mises en forme, que l'on a vues ci-dessus)
\item \textbf{R}, pour des propositions de refactoring
\item \textbf{W}, pour tout ce qui est en lien avec des avertissements
\item \textbf{E} pour les erreurs ou des bugs probablement présents dans le code
\item \textbf{F} pour les erreurs internes au fonctionnement de pylint, qui font que le traitement n'a pas pu aboutir.
\end{itemize}
Connaissant ceci, il est extrêmement pratique d'intégrer pylint au niveau des processus d'intégration continue, puisque la présence d'une
Connaissant ceci, il est extrêmement pratique d'intégrer pylint au niveau des processus d'intégration continue, puisque la présence d'une % TODO: ICI je pense qu'il manque quelque chose... Il semblerait que la conversion de ??? -> TeX ne se soit pas hyper bien passée.
Pylint propose également une option particulièrement efficace, qui prend le paramètre \texttt{--errors-only}, et qui n'affiche que les occurrences appartenant à la catégorie \textbf{E}.
Si nous souhaitons ignorer l'une de ces catégories, ce doit être fait explicitement : de cette manière, nous marquons notre approbation pour que pylint ignore consciemment un élément en particulier.
Cet élément peut être :
\begin{enumerate}
\item \textbf{Une ligne de code}
\item \textbf{Un bloc de code} - une fonction, une méthode, une classe, un module, ...
\item \textbf{Un bloc de code} - une fonction, une méthode, une classe, un module, \ldots
\item \textbf{Un projet entier}, en spécifiant la non-prise en compte au niveau du fichier \texttt{.pylintrc}, qui contient
\end{enumerate}
@ -496,10 +437,10 @@ Cet élément peut être:
\section{Formatage de code}
Nous avons parlé ci-dessous de style de codage pour Python (PEP8), de style de rédaction pour la documentation (PEP257), d'un vérificateur pour nous indiquer quels morceaux de code doivent absolument être revus, ...
Nous avons parlé ci-dessous de style de codage pour Python (PEP8), de style de rédaction pour la documentation (PEP257), d'un vérificateur pour nous indiquer quels morceaux de code doivent absolument être revus, \ldots
Reste que ces tâches sont parfois (très) souvent fastidieuses: écrire un code propre et systématiquement cohérent est une tâche ardue.
Heureusement, il existe plusieurs outils pour nous aider au niveau du formatage automatique.
Même si elle n'est pas parfaite, la librairie \href{https://black.readthedocs.io/en/stable/}{Black} arrive à un très bon compromis entre
Même si elle n'est pas parfaite, la librairie \href{https://black.readthedocs.io/en/stable/}{Black} arrive à un très bon compromis entre :
\begin{itemize}
\item Clarté du code
@ -513,25 +454,19 @@ Même Pylint arrivera parfois à râler.
Mais ce formatage conviendra dans 97,83\% des cas (au moins).
\begin{quote}
By using Black, you agree to cede control over minutiae of
hand-formatting. In return, Black gives you speed, determinism, and
freedom from pycodestyle nagging about formatting. You will save time
and mental energy for more important matters.
By using Black, you agree to cede control over minutiae of hand-formatting.
In return, Black gives you speed, determinism, and freedom from pycodestyle nagging about formatting.
You will save time and mental energy for more important matters.
Black makes code review faster by producing the smallest diffs possible.
Blackened code looks the same regardless of the project you're reading.
Formatting becomes transparent after a while and you can focus on the
content instead.
Formatting becomes transparent after a while and you can focus on the content instead.
\end{quote}
Traduit rapidement à partir de la langue de Batman: "\texttt{En utilisant
Black, vous cédez le contrôle sur le formatage de votre code. En retour,
Black vous fera gagner un max de temps, diminuera votre charge mentale
et fera revenir l'être aimé}". Mais la partie réellement intéressante
concerne le fait que "\texttt{Tout code qui sera passé par Black aura la
même forme, indépendamment du project sur lequel vous serez en train de
travailler. L'étape de formatage deviendra transparente, et vous pourrez
vous concentrer sur le contenu}".
Traduit rapidement à partir de la langue de Batman: "\texttt{En utilisant Black, vous cédez le contrôle sur le formatage de votre code.
En retour, Black vous fera gagner un max de temps, diminuera votre charge mentale et fera revenir l'être aimé}".
Mais la partie réellement intéressante concerne le fait que "\texttt{Tout code qui sera passé par Black aura la même forme, indépendamment du project sur lequel vous serez en train de travailler.
L'étape de formatage deviendra transparente, et vous pourrez vous concentrer sur le contenu}".
\section{Typage statique \index{PEP585}}
@ -586,36 +521,23 @@ Non seulement nous retournons la valeur \texttt{None} si la liste est vide alors
Pour corriger ceci, nous devons:
\begin{enumerate}
\item
Importer le type \texttt{Optional} et l'utiliser en sortie de notre
fonction \texttt{first\_int\_elem}
\item
Eviter de lui donner de mauvais paramètres ;-)²
\item Importer le type \texttt{Optional} et l'utiliser en sortie de notre fonction \texttt{first\_int\_elem}
\item Eviter de lui donner de mauvais paramètres ;-)²
\end{enumerate}
\section{Tests unitaires}
Comme tout bon \textbf{langage de programmation moderne} qui se respecte, Python embarque tout un environnement facilitant le lancement de tests;
Comme tout bon \textbf{langage de programmation moderne} qui se respecte, Python embarque tout un environnement facilitant le lancement de tests; % TODO: je me demande si ici aussi il ne manque pas des mots...
Une bonne pratique (parfois discutée) consiste cependant à switcher vers \texttt{pytest}, qui présente quelques avantages par rapport au module \texttt{unittest} :
\begin{itemize}
\item
Une syntaxe plus concise (au prix de \href{https://docs.pytest.org/en/reorganize-docs/new-docs/user/naming_conventions.html}{quelques conventions}, même si elles restent configurables): un test est une fonction, et ne doit pas obligatoirement faire partie d'une classe héritant de \texttt{TestCase} - la seule nécessité étant que cette fonction fasse partie d'un module commençant ou finissant par "test" (\texttt{test\_example.py} ou \texttt{example\_test.py}).
\item
Une compatibilité avec du code Python "classique" - vous ne devrez
donc retenir qu'un seul ensemble de commandes ;-)
\item
Des \emph{fixtures} faciles à réutiliser entre vos différents
composants
\item
Une compatibilité avec le reste de l'écosystème, dont la couverture de
code présentée ci-dessous.
\item Une syntaxe plus concise (au prix de \href{https://docs.pytest.org/en/reorganize-docs/new-docs/user/naming_conventions.html}{quelques conventions}, même si elles restent configurables) : un test est une fonction, et ne doit pas obligatoirement faire partie d'une classe héritant de \texttt{TestCase} - la seule nécessité étant que cette fonction fasse partie d'un module commençant ou finissant par "test" (\texttt{test\_example.py} ou \texttt{example\_test.py}).
\item Une compatibilité avec du code Python "classique" - vous ne devrez donc retenir qu'un seul ensemble de commandes ;-)
\item Des \emph{fixtures} faciles à réutiliser entre vos différents composants
\item Une compatibilité avec le reste de l'écosystème, dont la couverture de code présentée ci-dessous.
\end{itemize}
Ainsi, après installation, il nous suffit de créer notre module
\texttt{test\_models.py}, dans lequel nous allons simplement tester
l'addition d'un nombre et d'une chaîne de caractères (oui, c'est
complètement biesse; on est sur la partie théorique ici):
Ainsi, après installation, il nous suffit de créer notre module \texttt{test\_models.py}, dans lequel nous allons simplement tester l'addition d'un nombre et d'une chaîne de caractères (oui, c'est complètement biesse; on est sur la partie théorique ici) :
\begin{listing}
\begin{minted}{Python}
@ -741,19 +663,14 @@ L'exemple ci-dessous permettra, grâce à la commande \texttt{make\ coverage}, d
\caption{Un exemple de fichier Makefile}
\end{listing}
Pour la petite histoire, \texttt{make} peu sembler un peu désuet, mais
reste extrêmement efficace.
Pour la petite histoire, \texttt{make} peu sembler un peu désuet, mais reste extrêmement efficace.
\section{Conclusions (et intégration continue)}
\subsection{setup.cfg}
→ Faire le lien avec les settings → Faire le lien avec les douze
facteurs → Construction du fichier setup.cfg
→ Faire le lien avec les settings → Faire le lien avec les douze facteurs → Construction du fichier setup.cfg
\begin{verbatim}
[flake8]
@ -787,4 +704,4 @@ facteurs → Construction du fichier setup.cfg
django_coverage_plugin
\end{verbatim}
Mypy + black + pylint + flake8 + pyflakes + ...
Mypy + black + pylint + flake8 + pyflakes + \ldots