PyLint : le bon, le mauvais et le laid


  • Français


  • Prise à chaud : PyLint est vraiment bon !

    “PyLint peut vous sauver la vie” est une exagération, mais pas autant que vous ne le pensez ! PyLint peut vous éviter des bogues vraiment difficiles à trouver et compliqués. Au pire, cela peut vous faire gagner le temps d’un test. Au mieux, cela peut vous aider à éviter des erreurs de production compliquées.

    Le bon

    Je suis gêné de dire à quel point cela peut être courant. Nommer les tests est perpétuellement bizarre: Rien ne se soucie du nom, et il n’y a souvent pas de nom naturel à trouver. Par exemple, regardez ce code :

    def test_add_small():
        # Math, am I right?
        assert 1 + 1 == 3
       
    def test_add_large():
        assert 5 + 6 == 11
       
    def test_add_small():
        assert 1 + 10 == 11

    Le test fonctionne :

    collected 2 items                                                                        
    test.py ..
    2 passed

    Mais voici le hic : si vous remplacez un nom, l’infrastructure de test ignore joyeusement le test !

    En réalité, ces fichiers peuvent contenir des centaines de lignes et la personne qui ajoute le nouveau test peut ne pas connaître tous les noms. À moins que quelqu’un ne regarde attentivement la sortie du test, tout semble bien.

    Le pire de tout, le ajout du test prioritairela rupture de l’épreuve forcéeet le probleme qui resulte en prod peuvent être séparés par des jours, des mois ou même des années.

    PyLint le trouve

    Mais comme un bon ami, PyLint est là pour vous.

    test.py:8:0: E0102: function already defined line 1
         (function-redefined)

    Le mauvais

    Comme une sitcom des années 90, plus vous entrez dans PyLint, plus cela devient problématique. Il s’agit d’un code tout à fait raisonnable pour un programme de modélisation d’inventaire :

    """Inventory abstractions"""

    import attrs

    @attrs.define
    class Laptop:
        """A laptop"""
        ident: str
        cpu: str

    Il semble que PyLint ait des opinions (probablement formées dans les années 90) et n’ait pas peur de les énoncer comme des faits :

    $ pylint laptop.py | sed -n '/^laptop/s/[^ ]*: //p'
    R0903: Too few public methods (0/2) (too-few-public-methods)

    Le moche

    Vous avez toujours voulu ajouter votre propre opinion non vérifiée à un outil utilisé par des millions de personnes ? PyLint compte 12 millions de téléchargements mensuels.

    “Les gens désactiveront simplement l’ensemble de la vérification si c’est trop pointilleux.” —PyLint numéro 6987, 3 juillet 2022

    L’attitude qu’il adopte envers l’ajout d’un test avec potentiellement de nombreux faux positifs est…“eh.”

    Le faire fonctionner pour vous

    PyLint va bien, mais vous devez interagir avec lui avec précaution. Voici les trois choses que je recommande pour que PyLint fonctionne pour vous.

    1. Épinglez-le

    Épinglez la version de PyLint que vous utilisez pour éviter toute surprise !

    Dans ton .toml dossier:

    [project.optional-dependencies]
    pylint = ["pylint"]

    Dans votre code :

    from unittest import mock

    Cela correspond à un code comme celui-ci :

    # noxfile.py
    ...
    @nox.session(python=VERSIONS[-1])
    def refresh_deps(session):
        """Refresh the requirements-*.txt files"""
        session.install("pip-tools")
        for deps in [..., "pylint"]:
            session.run(
                "pip-compile",
                "--extra",
                deps,
                "pyproject.toml",
                "--output-file",
                f"requirements-{deps}.txt",
            )

    2. Refuser par défaut

    Désactivez toutes les vérifications. Activez ensuite ceux qui, selon vous, ont un rapport valeur/faux positif élevé. (Pas seulement le rapport faux négatif/faux positif !)

    # noxfile.py
    ...
    @nox.session(python="3.10")
    def lint(session):
        files = ["src/", "noxfile.py"]
        session.install("-r", "requirements-pylint.txt")
        session.install("-e", ".")
        session.run(
            "pylint",
            "--disable=all",
            *(f"--enable={checker}" for checker in checkers)
            "src",
        )

    3. Dames

    Ce sont quelques-uns de ceux que j’aime. Appliquer la cohérence dans le projet, éviter certaines erreurs évidentes.

    checkers = [
        "missing-class-docstring",
        "missing-function-docstring",
        "missing-module-docstring",
        "function-redefined",
    ]

    Utiliser PyLint

    Vous pouvez ne prendre que les bonnes parties de PyLint. Exécutez-le dans CI pour maintenir la cohérence et utilisez les vérificateurs de valeur la plus élevée.

    Perdez les mauvaises parties : vérificateurs de refus par défaut.

    Évitez les parties moches : épinglez la version pour éviter les surprises.

    Source

    Houssen Moshinaly

    Pour contacter personnellement le taulier :

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Copy code