175 votes

En Python, comment capter les avertissements comme s'il s'agissait d'exceptions ?

Une bibliothèque tierce (écrite en C) que j'utilise dans mon code python émet des avertissements. Je veux pouvoir utiliser la syntaxe try except pour gérer correctement ces avertissements. Y a-t-il un moyen de le faire ?

207voto

niekas Points 1228

Pour traiter les avertissements comme des erreurs, utilisez simplement ceci :

import warnings
warnings.filterwarnings("error")

Après cela, vous serez en mesure de capturer des avertissements identiques à des erreurs, par exemple, cela fonctionnera :

try:
    some_heavy_calculations()
except RuntimeWarning:
    import ipdb; ipdb.set_trace()

P.S. a ajouté cette réponse parce que la meilleure réponse dans les commentaires contient une faute d'orthographe : filterwarnigns au lieu de filterwarnings.

69voto

Bobby Powers Points 1210

Pour citer le manuel de python (27.6.4. Avertissements de test) :

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a warning.
    fxn()
    # Verify some things
    assert len(w) == 1
    assert issubclass(w[-1].category, DeprecationWarning)
    assert "deprecated" in str(w[-1].message)

32voto

azmeuk Points 156

Si vous voulez juste que votre script échoue sur les avertissements, vous pouvez invoquer python avec l'argument-W :

python -W error foobar.py

21voto

mcqwerty Points 2106

Voici une variante qui explique plus clairement comment utiliser uniquement vos avertissements personnalisés.

import warnings
with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")

    # Call some code that triggers a custom warning.
    functionThatRaisesWarning()

    # ignore any non-custom warnings that may be in the list
    w = filter(lambda i: issubclass(i.category, UserWarning), w)

    if len(w):
        # do something with the first warning
        email_admins(w[0].message)

6voto

Collin Anderson Points 952

Dans certains cas, vous devez utiliser ctypes pour transformer les avertissements en erreurs. Par exemple :

str(b'test')  # no error
import warnings
warnings.simplefilter('error', BytesWarning)
str(b'test')  # still no error
import ctypes
ctypes.c_int.in_dll(ctypes.pythonapi, 'Py_BytesWarningFlag').value = 2
str(b'test')  # this raises an error

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