web-dev-qa-db-fra.com

Obtenez le suivi des avertissements

Dans numpy, nous pouvons faire np.seterr(invalid='raise') pour obtenir un suivi des avertissements générant une erreur à la place (voir ce post ).

  • Existe-t-il un moyen général de retrouver les avertissements?
  • Puis-je faire python pour donner un traceback, lorsqu'un avertissement est émis?
61
embert

Vous pouvez obtenir ce que vous voulez en attribuant à warnings.showwarning. Le documentation du module d'avertissements lui-même vous recommande de le faire, donc ce n'est pas que vous êtes tenté par le côté obscur de la source . :)

Vous pouvez remplacer cette fonction par une implémentation alternative en affectant à warnings.showwarning.

Vous pouvez définir une nouvelle fonction qui fait ce que warning.showwarning fait normalement et en plus il imprime la pile. Ensuite, vous le placez à la place de l'original:

import traceback
import warnings
import sys

def warn_with_traceback(message, category, filename, lineno, file=None, line=None):

    log = file if hasattr(file,'write') else sys.stderr
    traceback.print_stack(file=log)
    log.write(warnings.formatwarning(message, category, filename, lineno, line))

warnings.showwarning = warn_with_traceback

Après cela, chaque avertissement imprimera la trace de la pile ainsi que le message d'avertissement. Tenez compte, cependant, que si l'avertissement est ignoré parce qu'il n'est pas le premier, rien ne se passera, vous devez donc toujours exécuter:

warnings.simplefilter("always")

Vous pouvez obtenir un contrôle similaire à celui numpy.seterr donne à travers les filtres du module warning

Si ce que vous voulez est python pour signaler chaque avertissement à chaque fois qu'il est déclenché et pas seulement la première fois, vous pouvez inclure quelque chose comme:

import warnings
warnings.simplefilter("always")

Vous pouvez obtenir d'autres comportements en passant différentes chaînes comme arguments. En utilisant la même fonction, vous pouvez également spécifier différents comportements pour les avertissements en fonction du module qui les a déclenchés, du message qu'ils fournissent, de la classe d'avertissement, de la ligne de code qui le provoque, etc.

Vous pouvez consulter la liste dans la documentation du module

Par exemple, vous pouvez définir tous les avertissements pour déclencher des exceptions, sauf le DeprecationWarnings qui doit être complètement ignoré:

import warnings
warnings.simplefilter("error")
warnings.simplefilter("ignore", DeprecationWarning)

De cette façon, vous obtenez le traçage complet pour chaque avertissement déclenché comme erreur (uniquement le premier, car l'exécution s'arrêtera ... mais vous pouvez les traiter un par un et créer un filtre pour ignorer ceux que vous ne voulez pas entendre encore une fois ...

61
mgab

Exécutez votre programme comme

python -W error myprogram.py

Cela rend tous les avertissements fatals, voir ici pour plus d'informations

17
Jakob Bowyer