diff --git a/2023-pyconfr-sphinx-lint.md b/2023-pyconfr-sphinx-lint.md index e613a77..4a2b20c 100644 --- a/2023-pyconfr-sphinx-lint.md +++ b/2023-pyconfr-sphinx-lint.md @@ -1,22 +1,33 @@ # sphinx-lint - + + Un linter pour ta doc.
-Julien Palard +Julien Palard -CPython core dev
-Sysadmin de l’AFPy
-hackinscience.org
-…
+## Julien Palard + + + +- CPython core dev +- Sysadmin à l’AFPy +- hackinscience.org + +Notes: + +- Je m’occupe surtout de docs.python.org +- Formateur, indépendant, faites passer le mot :) # Pourquoi ? +Notes: + Trouver des fautes de frappe dans du rst, ni plus, ni moins. ## Depuis quand ? @@ -28,38 +39,46 @@ Date: Sat Jan 3 20:30:15 2009 +0000 Dans `cpython` dans `Doc/tools/rstlint.py` ! -::: notes +Notes: Oui oui, Georg, l'auteur de Sphinx-doc. -## Depuis quand, quoi ? +# La motivation -Et dans `cpython` on en avait un autre, `make suspicious`. +`make suspicious` -Bien connu pour ses faux positifs. +Bien connu pour ses faux positifs, n'est-ce pas ? -::: notes +Notes: -Lui il date du portage de la doc de LaTeX à Sphinx, 2009 aussi. +Lui il date du portage de la doc de LaTeX à Sphinx, il était là pour +repérer les erreurs de portage. Il date donc de 2009 aussi. ## La motivation Remplacer `make suspicious` par un outil qui n’aurait **aucun** faux positif. -::: notes +Notes: -Et qui serait rapide ! - -Parler de la lenteur de `make suspicious`. +- Aucun faux positif == cool pour les contributeurs ! +- 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. +Sortir `rstlint.py` de `cpython/Doc/tools` pour que tout le monde puisse l'utiliser. +Notes: Et pour faciliter la contribution. + + +## La motivation + +![](static/2023-pyconfr-issue-open.png) + # Parsons du rst ! ## Le reStructuredText @@ -77,6 +96,7 @@ Lien_ `Un lien anonyme `__ ``` +Notes: Comme en Markdown, comme en Org. ## Le reStructuredText @@ -99,7 +119,7 @@ Donc oui le balisage et le texte interprété peuvent jouer le même rôle : ``ça`` c'est pareil que :literal:`ça`. ``` -::: notes +Notes: Mais comme en Python on a plus de méthodes que d'opérateurs… @@ -114,33 +134,37 @@ Les directives : .. image:: Lenna.jpg .. important:: - Elle s’appelle Lena Sjööblom. + Elle s’appelle *Lena Sjööblom*. ``` -::: notes +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, ... +Retenez-bien que le corps d'une directive peut contenir du reStructuredText ! ## Parsons du rst ! -C'est facile ! Ou pas… +Jusque-là, c’est facile ! -Exemple, comment on interprète : + +## Parsons du rst ! + +Maintenant, parsez ça, avec vos yeux : ```text *2 * x *a **b *.txt* ``` -::: notes +Notes: C'est tout en italique ! ## Parsons du rst ! -Vous voyez des balises, vous ? +Vous voyez du balisage, vous, ici ? ```text 2 * x ** 2 + 3 * x ** 3 @@ -152,7 +176,7 @@ a || b 2*x a**b O(N**2) e**(x*y) ``` -::: notes +Notes: Pas le parseur. Mais bon les règles sont bien documentées ♥ @@ -166,14 +190,14 @@ Regardons du côté des directives : ```text .. code-block:: python - def fib(x): + def fib(n): if n in (0, 1): return 1 x = n // 2 - return fib(x - 1) * fib(n - x - 1) + fib(x) * fib(n - x) + return fib(x-1) * fib(n-x-1) + fib(x) * fib(n-x) ``` -::: notes +Notes: Une directive peut avoir un corps, ici du code. @@ -190,7 +214,7 @@ Regardons du côté des directives : :alt: Lenna Sjööblom ``` -::: notes +Notes: Une directive peut avoir des options mais **pas de corps**. @@ -210,7 +234,7 @@ Regardons du côté des directives : aze.fr, 200, 200 ``` -::: notes +Notes: Une directive peut avoir des options **et** un corps. @@ -249,7 +273,7 @@ Une directive peut avoir des options **et** un corps. aze.fr ``` -::: notes +Notes: Les valeurs manquantes sont moins graves que les valeurs surnuméraires. @@ -259,9 +283,85 @@ Les valeurs manquantes sont moins graves que les valeurs surnuméraires. De toutes façons `sphinx-lint` ne cherche pas du rst valide, il cherche du rst invalide ! +## Mes amies les regex + +```python +SIMPLENAME = r"(?:(?!_)\w)+(?:[-._+:](?:(?!_)\w)+)*" +ROLE_GLUED_WITH_WORD_RE = re.compile( + fr"(^|\s)(?]""" +UNICODE_AFTER = r"[\p{Pe}\p{Pi}\p{Pf}\p{Pd}\p{Po}]" +re.compile( + fr"(?{start_string}\S{QUOTE_PAIRS_NLB}" + fr".*?(?<=\S){end_string})" + fr"(?=$|\s|\x00|{ASCII_AFTER}|{UNICODE_AFTER})" +) +``` + +Notes: Parfois pas. Mais vous connaissez `re.VERBOSE` ? + + +## Mes amies les regex + +```python +re.compile( + fr""" +(? + {start_string} # Inline markup start + \S # Inline markup start-strings must be + # immediately followed by non-whitespace. + # The inline markup end-string must be + # separated by at least one character + # from the start-string. + {QUOTE_PAIRS_NEGATIVE_LOOKBEHIND} + .*? + (?<=\S) # Inline markup end-strings must be + # immediately preceded by non-whitespace. + {end_string} # Inline markup end +) + +(?= # Inline markup end-strings must + $| # end a text block or + \s| # be immediately followed by whitespace, + \x00| + {ASCII_AFTER}| # one of the ASCII characters or a + {UNICODE_AFTER} # similar non-ASCII punctuation char. +) +""", + flags=re.VERBOSE | re.DOTALL, +) +``` + +Notes: Les commentaires sont un copié-collé de la spec ! + + # C’est utilisé ? -- CPython (depuis longtemps), devguide, peps, traductions, ... +- CPython (forcément…), devguide, peps, traductions, ... - neo4j-python-driver - pandas - Spyder IDE @@ -311,19 +411,46 @@ De toutes façons `sphinx-lint` ne cherche pas du rst valide, il cherche du rst +"datetime`. :const:`MINYEAR` es ``1``." ``` -... notes +Notes: Ils ont réparé plus de 300 erreurs ! +# Et les perfs ? + +```text +$ time make suspicious +real 1m10.416s +user 3m28.918s +sys 0m3.127s +``` + +```text +$ time make check # (c'est sphinx-lint derrière) +real 0m6.351s +user 0m43.478s +sys 0m0.227s +``` + # Et les faux positifs ? +- `make suspicious` → 400 +- `make checks` → 0 + + +## 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). +## Et `make suspicious` ? + +![](static/2023-pyconfr-issue-open.png) +![](static/2023-pyconfr-issue-close.png) + # OK, vendu ! Mais comment ça s’utilise ? @@ -337,14 +464,17 @@ $ sphinx-lint Bah, fais-le. +Notes: Pour Debian je veux bien le faire ;) + # Questions ? - Twitter : [@sizeof](https://twitter.com/sizeof) - Mastodon : [@mdk@mamot.fr](https://mamot.fr/@mdk) - XMPP : mdk@chapril.org -- HTTP : https://mdk.fr +- HTTP : https://mdk.fr (et https://discuss.afpy.org) - SMTP : julien@python.org -- Whatsapp : HAHAHA jamais. +- IRC : mdk sur irc.libera.chat (#python-fr, #afpy) +- Whatsapp : HaHa. Jamais. - Instagram : Et puis quoi encore ? -- TikTok : Euh, stop maintenant ? +- TikTok : Euh, bon, stop maintenant !? diff --git a/static/2023-pyconfr-banniere.png b/static/2023-pyconfr-banniere.png new file mode 100644 index 0000000..8caeb14 Binary files /dev/null and b/static/2023-pyconfr-banniere.png differ diff --git a/static/2023-pyconfr-issue-close.png b/static/2023-pyconfr-issue-close.png new file mode 100644 index 0000000..9d57c1a Binary files /dev/null and b/static/2023-pyconfr-issue-close.png differ diff --git a/static/2023-pyconfr-issue-open.png b/static/2023-pyconfr-issue-open.png new file mode 100644 index 0000000..fbe9299 Binary files /dev/null and b/static/2023-pyconfr-issue-open.png differ diff --git a/static/2023-snakes.svg b/static/2023-snakes.svg new file mode 100644 index 0000000..22a898a --- /dev/null +++ b/static/2023-snakes.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file