102 votes

Comment gérer AssertionError en Python et découvrir sur quelle ligne ou instruction elle s'est produite?

Je veux gérer les AssertionError à la fois pour cacher des parties inutiles de la trace de la pile à l'utilisateur et pour afficher un message expliquant pourquoi l'erreur s'est produite et ce que l'utilisateur devrait faire à ce sujet.

Y a-t-il un moyen de savoir sur quelle ligne ou instruction l'échec de l'instruction assert s'est produit dans le bloc except?

try:
    assert True
    assert 7 == 7
    assert 1 == 2
    # bien d'autres instructions comme ça
except AssertionError:
    print 'Houston, we have a problem.'
    print
    print 'Une erreur s'est produite à la ligne ???? dans l'instruction ???'
    exit(1)

Je ne veux pas avoir à ajouter cela à chaque instruction assert:

assert 7 == 7, "7 == 7"

parce que cela répète l'information.

101voto

phihag Points 89765

Utilisez le module traceback :

import sys
import traceback

try:
    assert True
    assert 7 == 7
    assert 1 == 2
    # beaucoup plus de déclarations de ce type
except AssertionError:
    _, _, tb = sys.exc_info()
    traceback.print_tb(tb) # Format fixe
    tb_info = traceback.extract_tb(tb)
    filename, line, func, text = tb_info[-1]

    print('Une erreur s\'est produite à la ligne {} dans l\'instruction {}'.format(line, text))
    exit(1)

53voto

Ryan_S Points 654

Le module de traceback et sys.exc_info sont excessifs pour retracer la source d'une exception. Tout est dans le traceback par défaut. Donc au lieu d'appeler exit(1) il suffit de re-lancer:

try:
    assert "birthday cake" == "ice cream cake", "aurait dû demander une tarte"
except AssertionError:
    print 'Houston, we have a problem.'
    raise

Ce qui donne la sortie suivante qui inclut l'instruction offensante et le numéro de ligne:

Houston, we have a problem.
Traceback (most recent call last):
  File "/tmp/poop.py", line 2, in 
    assert "birthday cake" == "ice cream cake", "aurait dû demander une tarte"
AssertionError: aurait dû demander une tarte

De même, le module logging facilite l'enregistrement d'une trace pour n'importe quelle exception (y compris celles qui sont capturées et jamais re-lancées):

import logging

try:
    assert False == True 
except AssertionError:
    logging.error("Rien n'est réel mais je ne peux pas abandonner...", exc_info=True)

1voto

kezzuki Points 11

Une façon plus simple serait :

essayer:
    assert True, 'premier'
    assert 7 == 7, 'deuxième'
    assert 1 == 2, 'troisième'
    # bien plus d'instructions comme celles-ci
sauf AssertionError as e:
    print(f'Échec de l'assertion à la ligne {str(e)}')
    exit(1)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X