# sphinx-lint Un linter pour ta doc.
Julien Palard CPython core dev
Sysadmin de l’AFPy
hackinscience.org

# Pourquoi ? Trouver des fautes de frappe dans du rst, ni plus, ni moins. ## Depuis quand ? ```text Author: Georg Brandl Date: Sat Jan 3 20:30:15 2009 +0000 ``` Dans `cpython` dans `Doc/tools/rstlint.py` ! ::: notes Oui oui, Georg, l'auteur de Sphinx-doc. ## Depuis quand, quoi ? Et dans `cpython` on en avait un autre, `make suspicious`. Bien connu pour ses faux positifs. ::: notes Lui il date du portage de la doc de LaTeX à Sphinx, 2009 aussi. ## La motivation Remplacer `make suspicious` par un outil qui n’aurait **aucun** faux positif. ::: notes Et qui serait rapide ! Parler de la lenteur de `make suspicious`. ## La motivation Sortir l’outil de `cpython/Doc/tools` pour que tout le monde puisse l'utiliser. # Parsons du rst ! ## Le reStructuredText Le balisage : ```text *En italique* **En gras** `Interprété` (dont le rôle peut changer) ``litéral`` Lien_ `Autre lien`_ `Encore un lien `_ `Un lien anonyme `__ ``` ## Le reStructuredText Les textes interprétés : ```text `while` C'est du texte interprété. :keyword:`while` Du texte interprété avec un « role marker » `while`:keyword: Ça lui donne un sens particulier. ``` ## Le reStructuredText Donc oui le balisage et le texte interprété peuvent jouer le même rôle : ```text *ça* c'est pareil que :emphasis:`ça`. **ça** c'est pareil que :strong:`ça`. ``ça`` c'est pareil que :literal:`ça`. ``` ::: notes Mais comme en Python on a plus de méthodes que d'opérateurs… En rst on a plus de rôles que de balises ! ## Le reStructuredText Les directives : ```text .. image:: Lenna.jpg .. important:: Elle s’appelle Lena Sjööblom. ``` ::: notes Je prends un gros raccourci : les directives ne sont qu'un bout de tout le balisage "explicite" comme les commentaires, les notes de bas de page, ... ## Parsons du rst ! C'est facile ! Ou pas… Exemple, comment on interprète : ```text *2 * x *a **b *.txt* ``` ::: notes C'est tout en italique ! ## Parsons du rst ! Vous voyez des balises, vous ? ```text 2 * x ** 2 + 3 * x ** 3 a || b "*" '|' (*) [*] {*} <*> ‘*’ 2*x a**b O(N**2) e**(x*y) ``` ::: notes Pas le parseur. Mais bon les règles sont bien documentées ♥ Mais on voit que les humains peuvent facilement faire des erreurs ici. ## Parsons du rst ! Regardons du côté des directives : ```text .. code-block:: python def fib(x): if n in (0, 1): return 1 x = n // 2 return fib(x - 1) * fib(n - x - 1) + fib(x) * fib(n - x) ``` ::: notes Une directive peut avoir un corps, ici du code. ## Parsons du rst ! Regardons du côté des directives : ```text .. image:: Lenna.jpg :height: 330px :width: 330px :scale: 50 % :alt: Lenna Sjööblom ``` ::: notes Une directive peut avoir des options mais **pas de corps**. ## Parsons du rst ! Regardons du côté des directives : ```text .. csv-table:: Domaines d'organismes publics :header: "name", "http_status", "https_status" :widths: 20, 10, 10 cgf.pf, 200, 200 dun.fr, 200, 200 caf.pf, 200, 200 aze.fr, 200, 200 ``` ::: notes Une directive peut avoir des options **et** un corps. ## Quiz ! ```text .. code-block:: python items = ["titi", "tata", "toto"] print(*items) .. important:: items = ["titi", "tata", "toto"] print(*items) ``` ## Quiz ! ```text .. csv-table:: Domaines d'organismes publics :header: "name", "http_status", "https_status" :widths: 20, 10, 10 cgf.pf, 200, 200, OK dun.fr, 200, 200, OK .. csv-table:: Domaines d'organismes publics :header: "name", "http_status", "https_status" :widths: 20, 10, 10 caf.pf aze.fr ``` ::: notes Les valeurs manquantes sont moins graves que les valeurs surnuméraires. ## Ne parsons pas de rst... De toutes façons `sphinx-lint` ne cherche pas du rst valide, il cherche du rst invalide ! # C’est utilisé ? - CPython (depuis longtemps), devguide, peps, traductions, ... - neo4j-python-driver - pandas - Spyder IDE - Sympy - Sphinx !!! # Ça trouve des bugs ? ## Dans les PEPS ```diff -`vcs ` library as +`vcs `_ library as ``` ## Dans sympy ```diff -... autoclass:: sympy.assumptions.predicates.order +.. autoclass:: sympy.assumptions.predicates.order ``` ```diff -:data:``sympy.parsing.sympy_parser.transformations`` +:data:`sympy.parsing.sympy_parser.transformations` ``` ```diff - `KanesMethod`` objects. + ``KanesMethod`` objects. ``` ## Dans la traduction > I just run the tool against library/ as a whole and it spit out a loooot of messages, so I thought that maybe it didn't work with our po files. ## Dans la traduction > After closer inspecting two of these files I found that they were indeed proper errors ```diff -"datetime`. :const:`MINYEAR` es` `1``." +"datetime`. :const:`MINYEAR` es ``1``." ``` ... notes Ils ont réparé plus de 300 erreurs ! # Et les faux positifs ? Ils se cachent bien : - Aucun dans la doc de Sphinx, c’est un bon test (beaucoup de rst dans du rst). - Aucun dans la doc de Python, c’est un bon test (286k lignes de rst). # OK, vendu ! Mais comment ça s’utilise ? ```text $ python -m pip install sphinx-lint $ sphinx-lint ``` # Bouh c’est pas packagé pour [distrib] Bah, fais-le. # Questions ? - Twitter : [@sizeof](https://twitter.com/sizeof) - Mastodon : [@mdk@mamot.fr](https://mamot.fr/@mdk) - XMPP : mdk@chapril.org - HTTP : https://mdk.fr - SMTP : julien@python.org - Whatsapp : HAHAHA jamais. - Instagram : Et puis quoi encore ? - TikTok : Euh, stop maintenant ?