Python est un langage très structuré. Il incite ainsi à la qualité du code par une rigueur rédactionnelle. Deux composantes principales de la qualité du code sont la documentation et les tests. Mais il s’agit aussi de deux aspects difficiles à imposer et à maintenir. Ceci fait que les approches dites Agile tendent à mettre en retrait la documentation par rapport à la production logicielle. Python propose une approche intéressante qui permet de documenter le code tout en s’assurant que cette documentation sera à jour. Suivez le guide.

Le point d’entrée : les Docstring.

Un code source Python accepte deux types de commentaires : d’une part les commentaires de fin de ligne commençant par le symbole #, d’autre part les documentations de modules, classes et méthodes : les docstring.

Le docstring est placé en début de fichier pour documenter le module et juste après la déclaration pour documenter la classe ou la méthode (et est donc indenté par rapport à la déclaration). Le contenu de la docstring est encadré de triples guillemets. Son contenu est régit par des conventions documentées par la PEP-257. Ainsi, si le doctring ne contient qu’une seule ligne, les deux triples guillemets doivent également être sur la même ligne. Si elle nécessite plusieurs lignes, alors la première contient un résumé de la documentation. Elle est suivi par une ligne vide puis le reste de la documentation avant d’ajouter une ligne vide avant les triples guillemets fermant. Voici un exemple en utilisant les deux implémentations de la suite de fibonacci de la documentation de Python :

Documentation et commentaires.

Avant d’aborder les questions d’utilité, une considération sur les utilisations. Les docstring servent à documenter un module, une classe, une méthode ou une fonction. Leur place est imposée. Les commentaires peuvent être insérés n’importe où dans le code. Ceci, associé à certains outils qui seront décrits ci-après, va décrire les règles d’usage :

  • Les docstrig étant exposés aux utilisateurs, elles doivent expliquer comment utiliser le module, la classe ou la méthode. Pour cela, il elles doivent résumer ce que réalise la fonction, détailler les variables et préciser ce qui est attendu et ce qui sera retourné. Elles permettent d’exploiter le composant sans avoir à analyser son implémentation.
  • Les commentaires ne sont accessibles que dans le code et sont destinés aux développeurs. Ils doivent expliquer pourquoi le code est présent. Ces commentaires concernent donc en général quelques lignes dont la présence ou le sens pourrait être sujet à question.

Exploitation des docstrings.

Il existe pour le développeur deux moyens pour accéder aux docstring : l’attribut __doc__, ou la fonction native help().

En dehors de cette exploitation immédiate, de nombreux outils tirent profit des docstrings. Exécutez donc la commande suivante dans un shell :

Pydoc est un petit utilitaire qui permet beaucoup de choses autour de la documentation, je vous invite à consulter sa page de documentation. Pydonc n’est qu’un outil parmi d’autres, Sphinx est un autre exemple d’outil exploitant les docstrings.

Doctest, l’assurance qualité de la documentation.

Malgré la présence des outils présentés précédemment, rien ne garanti l’adéquation entre la documentation et l’implémentation. C’est là qu’entrent en jeu le module doctest. Comme je l’ai écris précédemment, ce que l’on attend surtout d’une documentation, c’est de savoir comment utiliser le composant. Quoi de mieux que de présenter des cas d’utilisation, et de préférence des cas limite. Modifions donc le module avec le contenu suivant (seul la première fonction est présentée) :

D’un point de vue documentation, nous avons complété la docstring en incluant des cas d’utilisation. Ces cas sont présentés exactement comme si nous avions saisi une série d’instructions sur le shell Python et obtenu un affichage de résultat. Notez qu’il peut y avoir un enchainement de plusieurs commandes, comme l’affectation de variables (ligne 11).

Nous avons également ajouté 3 lignes importantes, les trois dernières (21 à 23). La condition exécute le corps si le module a été effectivement exécuté, en opposition à l’exploitation standard où le module sera simplement chargé. C’est alors qu’intervient doctest. Doctest va parcourir les docstrings à la recherche de tout ce qui ressemble à une session interactive, exécuter ce qui ressemble à une commande et vérifier que la sortie attendue correspond à la sortie effective. Si ce retour ne correspond pas, une erreur est affichée. Ainsi, si l’implémentation a évolué et que la documentation n’a pas été maintenu à jour, doctest le révèlera. Doctest peut aussi être utilisé pour vérifier que l’évolution n’a pas introduit de régressions. On peut donc dire que doctest permet de réaliser une série de tests unitaires sur la fonction documenté.

Bien entendu, doctest n’est pas un outil ultime, et il faut bien avoir conscience des limites. Doctest n’est pas réellement un outil de test unitaires, pas aussi complet que unittest, il ne permet que de s’assurer des cas « simples ». En effet, construire des mocks finirait par nuire à la documentation. Cependant, doctest souffre de la même limite que les tests unitaires : il ne garantissent le bon comportement que dans la limite de ce à quoi ils sont prévus. Ainsi, la qualité et la pertinence de la documentation dépend de celui qui l’aura écrite.

En conclusion

Avec les docstring et doctest, il est possible d’écrire en Python une documentation qui permet d’expliquer le fonctionnement d’une fonction, et de s’assurer de la validité de celle-ci. L’orientation « cas d’utilisation » permet bien d’orienter cette documentation vers ce qu’elle doit être : une explication de comment utiliser la fonction.

À propos de... Darko Stankovski

iT guy, photographe et papa 3.0, je vous fais partager mon expérience et découvertes dans ces domaines. Vous pouvez me suivre sur les liens ci-dessous.