28.6. warnings — Contrôle des alertes

Nouveau dans la version 2.1.

Code source: Lib/warnings.py


Les messages d’avertissement sont généralement émis dans les situations où il est utile d’alerter l’utilisateur d’un problème dans un programme, mais qu’il n’est pas justifié de lever une exception et de le terminer. Par exemple, on peut vouloir émettre un avertissement lorsqu’un programme utilise un module obsolète.

Les développeurs Python émettent des avertissements en appelant la fonction warn() définie dans ce module. (Les développeurs C utilisent PyErr_WarnEx() ; voir Gestion des exceptions pour plus d’informations).

Les messages d’avertissement sont normalement écrits sur sys.stderr, mais leurs effets peuvent être modifiés, il est possible d’ignorer tous les avertissements ou au contraire les transformer en exceptions. L’effet des avertissements peut varier en fonction de la catégorie d’avertissement (voir ci-dessous), de son texte et d’où il est émis. Les répétitions d’un même avertissement d’une même source sont généralement ignorés.

La gestion des avertissements se fait en deux étapes : premièrement, chaque fois qu’un avertissement est émis, le module détermine si un message doit être émis ou non ; ensuite, si un message doit être émis, il est formaté et affiché en utilisant une fonction qui peut être définie par l’utilisateur.

Un filtre (une séquence de règles) est utilisé pour décider si un message d’avertissement doit être émis ou non. Des règles peuvent être ajoutées au filtre en appelant filterwarnings() et remises à leur état par défaut en appelant resetwarnings().

L’affichage des messages d’avertissement se fait en appelant la fonction showwarning(), qui peut être redéfinie ; l’implémentation par défaut formate le message en appelant formatwarning(), qui peut également être réutilisée par une implémentation personnalisée.

Voir aussi

logging.captureWarnings() vous permet de gérer tous les avertissements avec l’infrastructure de journalisation standard.

28.6.1. Catégories d’avertissement

There are a number of built-in exceptions that represent warning categories. This categorization is useful to be able to filter out groups of warnings. The following warnings category classes are currently defined:

Classe

Description

Warning

Il s’agit de la classe de base de toutes les classes de catégories d’avertissement. C’est une sous-classe de Exception.

UserWarning

Catégorie par défaut pour warn().

DeprecationWarning

Base category for warnings about deprecated features (ignored by default).

SyntaxWarning

Catégorie de base pour les avertissements concernant les syntaxes douteuses.

RuntimeWarning

Catégorie de base pour les avertissements concernant les fonctionnalités douteuses à l’exécution.

FutureWarning

Base category for warnings about constructs that will change semantically in the future.

PendingDeprecationWarning

Catégorie de base pour les avertissements concernant les fonctionnalités qui seront obsolètes dans le futur (ignorée par défaut).

ImportWarning

Catégorie de base pour les avertissements déclenchés lors de l’importation d’un module (ignoré par défaut).

UnicodeWarning

Catégorie de base pour les avertissements relatifs à Unicode.

BytesWarning

Base category for warnings related to bytes and bytearray.

While these are technically built-in exceptions, they are documented here, because conceptually they belong to the warnings mechanism.

Le code utilisateur peut définir des catégories d’avertissement supplémentaires en héritant l’une des catégories d’avertissement standard. Une catégorie d’avertissement doit toujours hériter de la classe Warning.

Modifié dans la version 2.7: DeprecationWarning is ignored by default.

28.6.2. Le filtre des avertissements

Le filtre des avertissements contrôle si les avertissements sont ignorés, affichés ou transformés en erreurs (ce qui lève une exception).

Conceptually, the warnings filter maintains an ordered list of filter specifications; any specific warning is matched against each filter specification in the list in turn until a match is found; the match determines the disposition of the match. Each entry is a tuple of the form (action, message, category, module, lineno), where:

  • action est l’une des chaînes de caractères suivantes :

    Valeur

    Action

    "error"

    transforme les avertissements correspondants en exceptions

    "ignore"

    ignore les avertissements correspondants

    "always"

    affiche toujours les avertissements correspondants

    "default"

    print the first occurrence of matching warnings for each location where the warning is issued

    "module"

    print the first occurrence of matching warnings for each module where the warning is issued

    "once"

    n’affiche que la première occurrence des avertissements correspondants, quel que soit l’endroit où ils se trouvent

  • message est une chaîne de caractères contenant une expression régulière avec laquelle le début du message d’avertissement doit correspondre. L’expression est compilée pour être toujours insensible à la casse.

  • category est une classe (une sous-classe de Warning) dont la catégorie d’avertissement doit être une sous-classe afin de correspondre.

  • module est une chaîne de caractères contenant une expression régulière avec laquelle le nom du module doit correspondre. L’expression est compilée pour être sensible à la casse.

  • lineno est le numéro de ligne d’où l’avertissement doit provenir, ou 0 pour correspondre à tous les numéros de ligne.

Puisque que la classe Warning hérite de la classe Exception, pour transformer un avertissement en erreur, il suffit de lever category(message).

The warnings filter is initialized by -W options passed to the Python interpreter command line. The interpreter saves the arguments for all -W options without interpretation in sys.warnoptions; the warnings module parses these when it is first imported (invalid options are ignored, after printing a message to sys.stderr).

28.6.2.1. Default Warning Filters

By default, Python installs several warning filters, which can be overridden by the command-line options passed to -W and calls to filterwarnings().

28.6.3. Suppression temporaire des avertissements

If you are using code that you know will raise a warning, such as a deprecated function, but do not want to see the warning, then it is possible to suppress the warning using the catch_warnings context manager:

import warnings

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

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    fxn()

Dans le gestionnaire de contexte, tous les avertissements sont simplement ignorés. Ceci vous permet d’utiliser du code déclaré obsolète sans voir l’avertissement tout en ne supprimant pas l’avertissement pour un autre code qui pourrait ne pas être conscient de son utilisation de code déprécié. Remarque : ceci ne peut être garanti que dans une application utilisant un seul fil d’exécution. Si deux ou plusieurs threads utilisent le gestionnaire de contexte catch_warnings en même temps, le comportement est indéfini.

28.6.4. Tester les avertissements

Pour tester les avertissements générés par le code, utilisez le gestionnaire de contexte catch_warnings. Avec lui, vous pouvez temporairement modifier le filtre d’avertissements pour faciliter votre test. Par exemple, procédez comme suit pour capturer tous les avertissements levés à vérifier :

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)

Vous pouvez aussi faire en sorte que tous les avertissements soient des exceptions en utilisant error au lieu de always. Il faut savoir que si un avertissement a déjà été émis à cause d’une règle once ou default, quel que soit le filtre activé, l’avertissement ne sera pas revu à moins que le registre des avertissements lié à l’avertissement ait été vidé.

A sa sortie, le gestionnaire de contexte restaure le filtre des avertissements dans l’état où il était au démarrage du contexte. Cela empêche les tests de changer le filtre d’avertissements de manière inattendue entre les tests et d’aboutir à des résultats de test indéterminés. La fonction showwarning() du module est également restaurée à sa valeur originale. Remarque : ceci ne peut être garanti que dans une application mono-threadées. Si deux ou plusieurs fils d’exécution utilisent le gestionnaire de contexte catch_warnings en même temps, le comportement est indéfini.

Lorsque vous testez plusieurs opérations qui provoquent le même type d’avertissement, il est important de les tester d’une manière qui confirme que chaque opération provoque un nouvel avertissement (par exemple, définissez les avertissements comme exceptions et vérifiez que les opérations provoquent des exceptions, vérifiez que la longueur de la liste des avertissements continue à augmenter après chaque opération, ou bien supprimez les entrées précédentes de la liste des avertissements avant chaque nouvelle opération).

28.6.5. Updating Code For New Versions of Python

Warnings that are only of interest to the developer are ignored by default. As such you should make sure to test your code with typically ignored warnings made visible. You can do this from the command-line by passing -Wd to the interpreter (this is shorthand for -W default). This enables default handling for all warnings, including those that are ignored by default. To change what action is taken for encountered warnings you simply change what argument is passed to -W, e.g. -W error. See the -W flag for more details on what is possible.

To programmatically do the same as -Wd, use:

warnings.simplefilter('default')

Make sure to execute this code as soon as possible. This prevents the registering of what warnings have been raised from unexpectedly influencing how future warnings are treated.

Having certain warnings ignored by default is done to prevent a user from seeing warnings that are only of interest to the developer. As you do not necessarily have control over what interpreter a user uses to run their code, it is possible that a new version of Python will be released between your release cycles. The new interpreter release could trigger new warnings in your code that were not there in an older interpreter, e.g. DeprecationWarning for a module that you are using. While you as a developer want to be notified that your code is using a deprecated module, to a user this information is essentially noise and provides no benefit to them.

28.6.6. Fonctions disponibles

warnings.warn(message[, category[, stacklevel]])

Émet, ignore, ou transforme en exception un avertissement. L’argument category, s’il est donné, doit être une classe de catégorie d’avertissement (voir ci-dessus) ; et vaut par défaut UserWarning. Aussi message peut être une instance de Warning', auquel cas *category* sera ignoré et ``message.__class__` sera utilisé. Dans ce cas, le texte du message sera str(message). Cette fonction lève une exception si cet avertissement particulier émis est transformé en erreur par le filtre des avertissements, voir ci-dessus. L’argument stacklevel peut être utilisé par les fonctions wrapper écrites en Python, comme ceci :

def deprecation(message):
    warnings.warn(message, DeprecationWarning, stacklevel=2)

Fait en sorte que l’avertissement se réfère à l’appelant de deprecation() plutôt qu’à la source de deprecation() elle-même (puisque celle-ci irait à l’encontre du but du message d’avertissement).

warnings.warn_explicit(message, category, filename, lineno[, module[, registry[, module_globals]]])

Il s’agit d’une interface de bas niveau pour la fonctionnalité de warn(), en passant explicitement le message, la catégorie, le nom de fichier et le numéro de ligne, et éventuellement le nom du module et le registre (qui devrait être le dictionnaire __warningregistry__ du module). Le nom de module par défaut est le nom de fichier sans .py ; si aucun registre n’est passé, l’avertissement n’est jamais supprimé. message doit être une chaîne de caractères et category une sous-classe de Warning ou message peut être une instance de Warning, auquel cas category sera ignoré.

module_globals, s’il est fourni, doit être l’espace de nommage global utilisé par le code pour lequel l’avertissement est émis. (Cet argument est utilisé pour afficher les sources des modules trouvés dans les fichiers zip ou d’autres sources d’importation hors du système de fichiers).

Modifié dans la version 2.5: Added the module_globals parameter.

warnings.warnpy3k(message[, category[, stacklevel]])

Issue a warning related to Python 3.x deprecation. Warnings are only shown when Python is started with the -3 option. Like warn() message must be a string and category a subclass of Warning. warnpy3k() is using DeprecationWarning as default warning class.

Nouveau dans la version 2.6.

warnings.showwarning(message, category, filename, lineno[, file[, line]])

Write a warning to a file. The default implementation calls formatwarning(message, category, filename, lineno, line) and writes the resulting string to file, which defaults to sys.stderr. You may replace this function with an alternative implementation by assigning to warnings.showwarning. line is a line of source code to be included in the warning message; if line is not supplied, showwarning() will try to read the line specified by filename and lineno.

Modifié dans la version 2.7: The line argument is required to be supported.

warnings.formatwarning(message, category, filename, lineno[, line])

Formate un avertissement de la manière standard. Ceci renvoie une chaîne pouvant contenir des retours à la ligne se termine par un retour à la ligne. line est une ligne de code source à inclure dans le message d’avertissement ; si line n’est pas fourni, formatwarning() essaiera de lire la ligne spécifiée par filename et lineno.

Modifié dans la version 2.6: Added the line argument.

warnings.filterwarnings(action[, message[, category[, module[, lineno[, append]]]]])

Insère une entrée dans la liste de warning filter specifications. L’entrée est insérée à l’avant par défaut ; si append est vrai, elle est insérée à la fin. Il vérifie le type des arguments, compile les expressions régulières message et module, et les insère sous forme de tuple dans la liste des filtres d’avertissements. Les entrées plus proches du début de la liste ont priorité sur les entrées plus loin dans la liste. Les arguments omis ont par défaut une valeur qui correspond à tout.

warnings.simplefilter(action[, category[, lineno[, append]]])

Insère une entrée simple dans la liste de spécifications du filtre d’avertissements. La signification des paramètres de fonction est la même que pour filterwarnings(), mais les expressions régulières ne sont pas nécessaires car le filtre inséré correspond toujours à n’importe quel message dans n’importe quel module tant que la catégorie et le numéro de ligne correspondent.

warnings.resetwarnings()

Réinitialise le filtre des avertissements. Ceci supprime l’effet de tous les appels précédents à filterwarnings(), y compris celui de l’option -W des options de ligne de commande et des appels à simplefilter().

28.6.7. Gestionnaires de contexte disponibles

class warnings.catch_warnings([*, record=False, module=None])

Un gestionnaire de contexte qui copie et, à la sortie, restaure le filtre des avertissements et la fonction showwarning(). Si l’argument record est False (par défaut), le gestionnaire de contexte retourne None en entrant. Si record est True, une liste est renvoyée qui est progressivement remplie d’objets comme vus par une fonction custom showwarning' (qui supprime également la sortie vers ``sys.stdout`()). Chaque objet de la liste a des attributs avec les mêmes noms que les arguments de showwarning().

L’argument module prend un module qui sera utilisé à la place du module renvoyé lors de l’importation warnings dont le filtre sera protégé. Cet argument existe principalement pour tester le module warnings lui-même.

Note

Le gestionnaire catch_warnings fonctionne en remplaçant puis en restaurant plus tard la fonction showwarning() du module et la liste interne des spécifications du filtre. Cela signifie que le gestionnaire de contexte modifie l’état global et n’est donc pas prévisible avec plusieurs fils d’exécution.

Note

In Python 3, the arguments to the constructor for catch_warnings are keyword-only arguments.

Nouveau dans la version 2.6.