Déboguer un programme

Signaler

La phase de débogage d’un programme, qui consiste à rechercher les erreurs de programmation, est très gourmande en temps. Ceci est particulièrement vrai avec Python dont le typage dynamique repousse la découverte des fautes au moment de l’exécution.

I. Le traceback de Python

Lorsque l’interpréteur Python rencontre un problème, une exception est levée. Si elle n’est pas capturée, cette exception provoque l’arrêt du programme et l’affichage d’un message appelé traceback. Ce message permet de connaître la nature et le contexte de l’incident.

Lire l’intégralité des messages d’erreur et se familiariser avec eux permet à la longue de gagner énormément de temps.

II. Erreurs de syntaxe

Les erreurs de syntaxe empêchent l’interpréteur de comprendre le code écrit et provoquent la levée d’une exception avant même l’exécution du code. Ces erreurs sont souvent faciles à trouver :

parenthèse, crochet ou guillemet mal fermé (SyntaxError) ;

mauvaise indentation (IndentationError).

À noter

Attention, le traceback indique la ligne où l’erreur a été détectée (qui n’est pas forcément la ligne où l’erreur a été commise).

Exemple :

2d159880-17d4-4043-b43c-35fc1cbcbf55

55cc3585-6b9e-47a4-8c0a-f9824b696e0d

L’erreur, signalée ligne 3, est en fait ligne 2 : il manque une parenthèse fermante. Comme les instructions peuvent courir sur plusieurs lignes, elle n’est détectée que ligne 3 !

À noter

Mélanger des espaces et des tabulations pour indenter le code est souvent incorrect, et toujours déconseillé. Ce type d’erreur est difficile à repérer car la largeur d’une tabulation peut correspondre à celle de quelques espaces. Il est conseillé de configurer son éditeur pour que l’appui sur la touche 84507761-8550-45a5-8e32-f82fcccacf8f provoque l’insertion de 4 espaces (qui est le niveau d’indentation conseillé en Python).

III. Erreurs à l’exécution

Les exceptions levées à l’exécution sont plus difficiles à trouver, car elles nécessitent de comprendre (à différents degrés) l’exécution du code. Elles sont aussi plus variées :

NameError : un nom de variable a-t-il été mal orthographié ?

IndexError : l’indice utilisé est-il en dehors de la liste ?

TypeError : a-t-on essayé d’ajouter un nombre à une chaîne de caractères ?

Outre le type d’exception et la ligne l’ayant levée, le traceback contient un historique des appels de fonctions (la pile des appels) permettant de connaître le contexte d’exécution. La recherche d’une erreur s’apparente alors à une enquête : depuis l’endroit où l’erreur s’est déclarée, on remonte le fil d’exécution pour en déterminer la cause, qui peut être à un tout autre endroit (le traceback se lit pour cette raison de bas en haut) :

d5ff3a46-b38e-484b-9cca-d86c9e318ea1

Lors de l’exécution du fichier error.py, une exception de type ZeroDivision­Error a été levée, ligne 3 (a = a / (b + c)), dans la fonction f1. La fonction en question a été exécutée suite à un appel sur la ligne 7, dans la fonction f2, qui elle-même a été appelée par la ligne 10 du programme principal.

À noter

Grace Hopper rapporte en 1947 un cas de bug devenu célèbre : il s’agissait d’un insecte (bug en anglais) ayant provoqué des erreurs de calcul dans un ordinateur Mark II.

IV. Débogueur

Le débogueur permet de dérouler un programme pas à pas et de vérifier l’état de chaque variable. C’est un outil parfois indispensable pour comprendre des bugs complexes.

Le débogueur post-mortem permet d’inspecter l’état du programme (contenu des variables par exemple) à partir du lieu où l’exception a été levée. C’est souvent suffisant pour comprendre une erreur.

La plupart des environnements de développement proposent un débogueur.