Analyse statique de code Python avec Pylint

  1. Présentation de Pylint

Pylint est un analyseur statique dédié à Python. Il détecte les erreurs de syntaxe, les écarts par rapport aux conventions d'écriture, les problèmes potentiels et les redondances. L'outil s'utilise principalement en ligne de commande, mais il peut également être invoqué comme un module Python. Il offre un système de configuration avancé via un fichier .pylintrc et la possibilité d'étendre ses capacités par des plugins.

  1. Installation et génération d'une configuration

L'installation s'effectue avec pip. La commende suivante installe Pylint dans l'environnement actif :

$ pip install pylint
$ pylint --version
pylint 2.1.1
astroid 2.0.4
Python 3.6.0

Pour générer un fichier de configuration par défaut, on redirige la sortie de l'option --generate-rcfile vers un fichier. Par exemple, le fragment ci-dessous crée un fichier nommé .pylintrc dans le répertoire courant :

$ pylint --generate-rcfile > .pylintrc
$ ls -lh .pylintrc
-rw-r--r-- 1 user user 18K Nov 12 10:23 .pylintrc

  1. Options de ligne de commande principales

  • --generate-rcfile : génère un fichier de configuration modèle.
  • --rcfile=<chemin> : indique un fichier de configuration personnalisé.
  • --include-ids=<y_or_n> : inclut l'identifiant de chaque message dans la sortie.
  • --reports=<y_or_n> ou -r : active ou désactive la section de rapport statistique.
  • --output-format=<format> ou -f : choisit le format de sortie (text, json, colorized, html).
  • --disable=<msg-ids> : désactive les messages identifiés.
  1. Analyse d'un seul module

Soit le fichier exemple.py contenant le code suivant :

from datetime import datetime


def afficher_heure():
    print(datetime.now().strftime("%H:%M:%S"))


afficher_heure()

On lance l'analyse avec Pylint de la manière suivante :

$ pylint --rcfile=.pylintrc exemple.py
************* Module exemple
exemple.py:1:0: C0114: Missing module docstring (missing-module-docstring)
exemple.py:4:0: C0116: Missing function or method docstring (missing-function-docstring)

-----------------------------------
Your code has been rated at 5.00/10

L'ajout du paramètre -ry affiche le rapport détaillé, tandis que -rn le masque :

$ pylint -ry --rcfile=.pylintrc exemple.py
************* Module exemple
exemple.py:1:0: C0114: Missing module docstring (missing-module-docstring)
exemple.py:4:0: C0116: Missing function or method docstring (missing-function-docstring)


Report
======
4 statements analysed.

Statistics by type
------------------

+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |1      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|method   |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|function |1      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+



Raw metrics
-----------

+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |5      |50.00 |NC       |NC         |
+----------+-------+------+---------+-----------+
|docstring |0      |0.00  |NC       |NC         |
+----------+-------+------+---------+-----------+
|comment   |0      |0.00  |NC       |NC         |
+----------+-------+------+---------+-----------+
|empty     |5      |50.00 |NC       |NC         |
+----------+-------+------+---------+-----------+



Messages by category
--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |2      |NC       |NC         |
+-----------+-------+---------+-----------+
|refactor   |0      |NC       |NC         |
+-----------+-------+---------+-----------+
|warning    |0      |NC       |NC         |
+-----------+-------+---------+-----------+
|error      |0      |NC       |NC         |
+-----------+-------+---------+-----------+



Messages
--------

+------------------+------------+
|message id        |occurrences |
+==================+============+
|missing-docstring |2           |
+------------------+------------+




-----------------------------------
Your code has been rated at 5.00/10

Les messages sont classés par catégorie : C pour convention, W pour avertissement, R pour refactoring, E pour erreur. Le format général d'un message est le suivant : fichier:ligne:colonne: CODE: description (id).

  1. Analyse d'un projet complet

Pour analyser un ensemble de modules, il suffit de passer le nom du package en argument. Pylint explore alors l'arborescence et vérifie chaque module. Considérons l'arborescence suivente :

$ tree monprojet
monprojet/
├── __init__.py
├── calcul.py
├── utils.py
└── lib
    ├── __init__.py
    └── helpers.py

L'analyse complète du package se lance ainsi :

$ pylint --rcfile=.pylintrc monprojet/
************* Module monprojet.calcul
monprojet\calcul.py:1:0: C0103: Module name "calcul" doesn't conform to snake_case naming style (invalid-name)
monprojet\calcul.py:1:0: C0114: Missing module docstring (missing-module-docstring)
monprojet\calcul.py:5:0: C0116: Missing function or method docstring (missing-function-docstring)
monprojet\calcul.py:10:0: C0103: Constant name "resultat" doesn't conform to UPPER_CASE naming style (invalid-name)
monprojet\calcul.py:3:0: C0411: standard import "import os" should be placed before "import monprojet.utils" (wrong-import-order)
************* Module monprojet.utils
monprojet\utils.py:1:0: C0114: Missing module docstring (missing-module-docstring)
monprojet\utils.py:4:0: C0116: Missing function or method docstring (missing-function-docstring)
monprojet\utils.py:14:4: R1705: Unnecessary "else" after "return" (no-else-return)
************* Module monprojet.lib.helpers
monprojet\lib\helpers.py:1:0: C0114: Missing module docstring (missing-module-docstring)
monprojet\lib\helpers.py:3:0: C0116: Missing function or method docstring (missing-function-docstring)
************* Module monprojet.lib
monprojet\lib\__init__.py:1:0: C0114: Missing module docstring (missing-module-docstring)

-----------------------------------
Your code has been rated at 3.18/10

  1. Intégration à PyCharm

Pour utiliser Pylint directement dans PyCharm, il est possible d'ajouter un outil externe :

  1. Ouvrir File > Settings > Tools > External Tools.
  2. Ajouter un nouvel outil avec le programme pylint et les arguments désirés.
  3. Valider et appliquer.

L'outil devient alors accessible depuis le menu Tools, ce qui permet da'nalyser rapidement le fichier actif.

  1. Outils complémentaires

Outre Pylint, plusieurs autres outilles permettent d'améliorer la qualité du code Python.

pycodestyle

Outil qui vérifie la conformité au style PEP 8. Il s'installe et s'utilise simplement :

$ pip install pycodestyle
$ pycodestyle mon_script.py

flake8

Flake8 combine pyflakes et pycodestyle pour fournir une analyse de style et de logique. Il s'utilise de manière similaire :

$ pip install flake8
$ flake8 mon_script.py

Étiquettes: Pylint Python analyse statique PyCharm pycodestyle

Publié le 7 juillet à 21h16