warningsWarning control警告控制

Source code: Lib/warnings.py


Warning messages are typically issued in situations where it is useful to alert the user of some condition in a program, where that condition (normally) doesn’t warrant raising an exception and terminating the program. 警告消息通常是在以下情况下发出的:警告用户程序中的某些情况是有用的,而该情况(通常)不需要引发异常并终止程序。For example, one might want to issue a warning when a program uses an obsolete module.例如,当程序使用过时的模块时,可能需要发出警告。

Python programmers issue warnings by calling the warn() function defined in this module. (C programmers use PyErr_WarnEx(); see Exception Handling for details).Python程序员通过调用此模块中定义的warn()函数发出警告。(C程序员使用PyErr_WarnEx();有关详细信息,请参阅异常处理)。

Warning messages are normally written to sys.stderr, but their disposition can be changed flexibly, from ignoring all warnings to turning them into exceptions. 警告消息通常会写入sys.stderr,但它们的处理方式可以灵活更改,从忽略所有警告到将其转换为异常。The disposition of warnings can vary based on the warning category, the text of the warning message, and the source location where it is issued. 警告的处置可能因警告类别、警告消息的文本和发出警告消息的源位置而异。Repetitions of a particular warning for the same source location are typically suppressed.通常会抑制对同一源位置重复特定警告。

There are two stages in warning control: first, each time a warning is issued, a determination is made whether a message should be issued or not; next, if a message is to be issued, it is formatted and printed using a user-settable hook.警告控制分为两个阶段:第一,每次发出警告时,都要确定是否应该发出消息;接下来,如果要发出消息,则使用用户可设置的挂钩对其进行格式化和打印。

The determination whether to issue a warning message is controlled by the warning filter, which is a sequence of matching rules and actions. 是否发出警告消息的确定由警告筛选器控制,该过滤器是匹配规则和动作的序列。Rules can be added to the filter by calling filterwarnings() and reset to its default state by calling resetwarnings().可以通过调用filterwarnings()将规则添加到筛选器中,并通过调用resetwarnings()将其重置为默认状态。

The printing of warning messages is done by calling showwarning(), which may be overridden; the default implementation of this function formats the message by calling formatwarning(), which is also available for use by custom implementations.警告消息的打印是通过调用showwarning()完成的,它可能会被重写;该函数的默认实现通过调用formatwarning()来格式化消息,自定义实现也可以使用该函数。

See also

logging.captureWarnings() allows you to handle all warnings with the standard logging infrastructure.允许您使用标准日志记录基础结构处理所有警告。

Warning Categories警告类别

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.这种分类对于筛选出警告组非常有用。

While these are technically built-in exceptions, they are documented here, because conceptually they belong to the warnings mechanism.虽然这些是技术上内置的异常,但在这里对它们进行了记录,因为从概念上讲,它们属于警告机制。

User code can define additional warning categories by subclassing one of the standard warning categories. 用户代码可以通过对标准警告类别之一进行子类化来定义其他警告类别。A warning category must always be a subclass of the Warning class.警告类别必须始终是Warning类的子类。

The following warnings category classes are currently defined:当前定义了以下警告类别类:

Class

Description描述

Warning

This is the base class of all warning category classes. 这是所有警告类别类的基类。It is a subclass of Exception.它是Exception的子类。

UserWarning

The default category for warn().warn()的默认类别。

DeprecationWarning

Base category for warnings about deprecated features when those warnings are intended for other Python developers (ignored by default, unless triggered by code in __main__).当这些警告针对其他Python开发人员时(默认情况下忽略,除非由__main__中的代码触发),则这些警告是关于已弃用功能的基本类别。

SyntaxWarning

Base category for warnings about dubious syntactic features.有关可疑语法特征的警告的基本类别。

RuntimeWarning

Base category for warnings about dubious runtime features.有关可疑运行时功能的警告的基本类别。

FutureWarning

Base category for warnings about deprecated features when those warnings are intended for end users of applications that are written in Python.当这些警告是针对用Python编写的应用程序的最终用户时,有关已弃用功能的警告的基本类别。

PendingDeprecationWarning

Base category for warnings about features that will be deprecated in the future (ignored by default).有关将来将被弃用的功能的警告的基本类别(默认情况下忽略)。

ImportWarning

Base category for warnings triggered during the process of importing a module (ignored by default).导入模块过程中触发的警告的基本类别(默认情况下忽略)。

UnicodeWarning

Base category for warnings related to Unicode.与Unicode相关的警告的基本类别。

BytesWarning

Base category for warnings related to bytes and bytearray.bytesbytearray数组相关的警告的基本类别。

ResourceWarning

Base category for warnings related to resource usage (ignored by default).与资源使用相关的警告的基本类别(默认情况下忽略)。

Changed in version 3.7:版本3.7中更改: Previously DeprecationWarning and FutureWarning were distinguished based on whether a feature was being removed entirely or changing its behaviour. 以前的DeprecationWarningFutureWarning是根据功能是否被完全删除或改变其行为来区分的。They are now distinguished based on their intended audience and the way they’re handled by the default warnings filters.它们现在根据其预期受众和默认警告筛选器处理它们的方式进行区分。

The Warnings Filter警告筛选器

The warnings filter controls whether warnings are ignored, displayed, or turned into errors (raising an 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 filter determines the disposition of the match. 从概念上讲,警告筛选器维护过滤器规范的有序列表;将任何特定警告依次与列表中的每个过滤器规范匹配,直到找到匹配;过滤器确定匹配的配置。Each entry is a tuple of the form (action, message, category, module, lineno), where:每个条目都是一个形式的元组(actionmessagecategorymodulelineno),其中:

  • action is one of the following strings:是以下字符串之一:

    Value价值

    Disposition性情

    "default"

    print the first occurrence of matching warnings for each location (module + line number) where the warning is issued为发出警告的每个位置(模块+行号)打印第一次出现的匹配警告

    "error"

    turn matching warnings into exceptions将匹配的警告转换为异常

    "ignore"

    never print matching warnings从不打印匹配的警告

    "always"

    always print matching warnings始终打印匹配的警告

    "module"

    print the first occurrence of matching warnings for each module where the warning is issued (regardless of line number)为发出警告的每个模块打印第一次匹配警告(无论行号如何)

    "once"

    print only the first occurrence of matching warnings, regardless of location无论位置如何,只打印第一次出现的匹配警告

  • message is a string containing a regular expression that the start of the warning message must match. 是包含警告消息开头必须匹配的正则表达式的字符串。The expression is compiled to always be case-insensitive.表达式被编译为始终不区分大小写。

  • category is a class (a subclass of Warning) of which the warning category must be a subclass in order to match.是一个类(Warning的子类),其警告类别必须是子类才能匹配。

  • module is a string containing a regular expression that the module name must match. 是包含模块名称必须匹配的正则表达式的字符串。The expression is compiled to be case-sensitive.表达式被编译为区分大小写。

  • lineno is an integer that the line number where the warning occurred must match, or 0 to match all line numbers.是发生警告的行号必须匹配的整数,或者是0以匹配所有行号。

Since the Warning class is derived from the built-in Exception class, to turn a warning into an error we simply raise category(message).由于Warning类是从内置的Exception类派生的,所以要将警告转换为错误,我们只需引发category(message)

If a warning is reported and doesn’t match any registered filter then the “default” action is applied (hence its name).如果报告的警告与任何注册的筛选器不匹配,则应用“默认”操作(因此得名)。

Describing Warning Filters描述警告筛选器

The warnings filter is initialized by -W options passed to the Python interpreter command line and the PYTHONWARNINGS environment variable. 警告筛选器由传递到Python解释器命令行和PYTHONWARNINGS环境变量的-W选项初始化。The interpreter saves the arguments for all supplied entries 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).解释器将所有提供的条目的参数保存在sys.warnoptions中,而不进行解释;warnings模块在首次导入时解析这些警告(在将消息打印到sys.stderr后,将忽略无效选项)。

Individual warnings filters are specified as a sequence of fields separated by colons:单个警告筛选器指定为一系列用冒号分隔的字段:

action:message:category:module:line

The meaning of each of these fields is as described in The Warnings Filter. 这些字段的含义如警告筛选器中所述。When listing multiple filters on a single line (as for PYTHONWARNINGS), the individual filters are separated by commas and the filters listed later take precedence over those listed before them (as they’re applied left-to-right, and the most recently applied filters take precedence over earlier ones).当在一行中列出多个筛选器时(PYTHONWARNINGS),单独的过滤器用逗号分隔,后面列出的过滤器优先于前面列出的过滤器(因为它们从左到右应用,最近应用的过滤器优先前面的过滤器)。

Commonly used warning filters apply to either all warnings, warnings in a particular category, or warnings raised by particular modules or packages. 常用的警告筛选器适用于所有警告、特定类别中的警告或特定模块或包引发的警告。Some examples:一些示例:

default                      # Show all warnings (even those ignored by default)
ignore # Ignore all warnings
error # Convert all warnings to errors
error::ResourceWarning # Treat ResourceWarning messages as errors
default::DeprecationWarning # Show DeprecationWarning messages
ignore,default:::mymodule # Only report warnings triggered by "mymodule"
error:::mymodule[.*] # Convert warnings to errors in "mymodule"
# and any subpackages of "mymodule"

Default Warning Filter默认警告筛选器

By default, Python installs several warning filters, which can be overridden by the -W command-line option, the PYTHONWARNINGS environment variable and calls to filterwarnings().默认情况下,Python会安装几个警告筛选器,这些过滤器可以被-W命令行选项、PYTHONWARNINGS环境变量和对filterwarnings()的调用覆盖。

In regular release builds, the default warning filter has the following entries (in order of precedence):在常规版本构建中,默认警告筛选器包含以下条目(按优先级排序):

default::DeprecationWarning:__main__
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
ignore::ImportWarning
ignore::ResourceWarning

In a debug build, the list of default warning filters is empty.调试生成中,默认警告筛选器列表为空。

Changed in version 3.2:版本3.2中更改: DeprecationWarning is now ignored by default in addition to PendingDeprecationWarning.PendingDeprecationWarning外,现在默认情况下忽略。

Changed in version 3.7:版本3.7中更改: DeprecationWarning is once again shown by default when triggered directly by code in __main__.__main__中的代码直接触发时,默认情况下再次显示DeprecationWarning

Changed in version 3.7:版本3.7中更改: BytesWarning no longer appears in the default filter list and is instead configured via sys.warnoptions when -b is specified twice.BytesWarning不再显示在默认筛选器列表中,而是在指定两次-b时通过sys.warnoptions进行配置。

Overriding the default filter覆盖默认筛选器

Developers of applications written in Python may wish to hide all Python level warnings from their users by default, and only display them when running tests or otherwise working on the application. 用Python编写的应用程序的开发人员可能希望在默认情况下向用户隐藏所有Python级别的警告,并仅在运行测试或以其他方式处理应用程序时显示这些警告。The sys.warnoptions attribute used to pass filter configurations to the interpreter can be used as a marker to indicate whether or not warnings should be disabled:用于将筛选器配置传递给解释器的sys.warnoptions属性可用作标记,指示是否应禁用警告:

import sys
if not sys.warnoptions:
import warnings
warnings.simplefilter("ignore")

Developers of test runners for Python code are advised to instead ensure that all warnings are displayed by default for the code under test, using code like:建议Python代码测试运行程序的开发人员使用以下代码确保默认情况下显示测试代码的所有警告:

import sys
if not sys.warnoptions:
import os, warnings
warnings.simplefilter("default") # Change the filter in this process
os.environ["PYTHONWARNINGS"] = "default" # Also affect subprocesses

Finally, developers of interactive shells that run user code in a namespace other than __main__ are advised to ensure that DeprecationWarning messages are made visible by default, using code like the following (where user_ns is the module used to execute code entered interactively):最后,建议在__main__以外的命名空间中运行用户代码的交互式shell的开发人员确保默认情况下使用如下代码(其中user_ns是用于执行交互式输入的代码的模块)使DeprecationWarning消息可见:

import warnings
warnings.filterwarnings("default", category=DeprecationWarning,
module=user_ns.get("__name__"))

Temporarily Suppressing Warnings临时抑制警告

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 (even when warnings have been explicitly configured via the command line), then it is possible to suppress the warning using the catch_warnings context manager:如果您使用的代码已知会引发警告,例如已弃用的函数,但不希望看到警告(即使通过命令行显式配置了警告),则可以使用catch_warnings上下文管理器抑制警告:

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

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

While within the context manager all warnings will simply be ignored. 在上下文管理器中,所有警告都将被忽略。This allows you to use known-deprecated code without having to see the warning while not suppressing the warning for other code that might not be aware of its use of deprecated code. 这允许您使用已知的不推荐使用的代码,而不必看到警告,同时也不会对可能不知道使用了不推荐使用代码的其他代码隐藏警告。Note: this can only be guaranteed in a single-threaded application. 注意:这只能在单线程应用程序中得到保证。If two or more threads use the catch_warnings context manager at the same time, the behavior is undefined.如果两个或多个线程同时使用catch_warnings上下文管理器,则行为未定义。

Testing Warnings测试警告

To test warnings raised by code, use the catch_warnings context manager. 要测试代码引发的警告,请使用catch_warnings上下文管理器。With it you can temporarily mutate the warnings filter to facilitate your testing. 有了它,您可以暂时改变警告筛选器,以便于测试。For instance, do the following to capture all raised warnings to check:例如,执行以下操作以捕获要检查的所有引发的警告:

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)

One can also cause all warnings to be exceptions by using error instead of always. 通过使用error而不是always,也可以使所有警告都成为异常。One thing to be aware of is that if a warning has already been raised because of a once/default rule, then no matter what filters are set the warning will not be seen again unless the warnings registry related to the warning has been cleared.需要注意的一点是,如果由于once/default规则而引发了警告,则无论设置了什么筛选器,除非已清除与警告相关的警告注册表,否则将不会再次看到警告。

Once the context manager exits, the warnings filter is restored to its state when the context was entered. 一旦上下文管理器退出,警告筛选器将恢复到输入上下文时的状态。This prevents tests from changing the warnings filter in unexpected ways between tests and leading to indeterminate test results. 这可以防止测试在测试之间以意外方式更改警告筛选器,并导致测试结果不确定。The showwarning() function in the module is also restored to its original value. 模块中的showwarning()函数也会恢复到其原始值。Note: this can only be guaranteed in a single-threaded application. 注意:这只能在单线程应用程序中得到保证。If two or more threads use the catch_warnings context manager at the same time, the behavior is undefined.如果两个或多个线程同时使用catch_warnings上下文管理器,则行为未定义。

When testing multiple operations that raise the same kind of warning, it is important to test them in a manner that confirms each operation is raising a new warning (e.g. set warnings to be raised as exceptions and check the operations raise exceptions, check that the length of the warning list continues to increase after each operation, or else delete the previous entries from the warnings list before each new operation).当测试引发相同类型警告的多个操作时,以确认每个操作都会引发新警告的方式对它们进行测试非常重要(例如,将要引发的警告设置为异常并检查操作引发异常,检查警告列表的长度在每个操作之后是否继续增加,或者在每个新操作之前从警告列表中删除以前的条目)。

Updating Code For New Versions of Dependencies更新新版本依赖项的代码

Warning categories that are primarily of interest to Python developers (rather than end users of applications written in Python) are ignored by default.默认情况下,Python开发人员(而不是用Python编写的应用程序的最终用户)主要感兴趣的警告类别将被忽略。

Notably, this “ignored by default” list includes DeprecationWarning (for every module except __main__), which means developers should make sure to test their code with typically ignored warnings made visible in order to receive timely notifications of future breaking API changes (whether in the standard library or third party packages).值得注意的是,这个“默认忽略”列表包括DeprecationWarning(针对除__main__之外的每个模块),这意味着开发人员应该确保测试代码时通常忽略的警告是可见的,以便及时收到未来重大API更改的通知(无论是在标准库还是第三方包中)。

In the ideal case, the code will have a suitable test suite, and the test runner will take care of implicitly enabling all warnings when running tests (the test runner provided by the unittest module does this).在理想情况下,代码将有一个合适的测试套件,测试运行器将在运行测试时隐式启用所有警告(由unittest模块提供的测试运行器执行此操作)。

In less ideal cases, applications can be checked for use of deprecated interfaces by passing -Wd to the Python interpreter (this is shorthand for -W default) or setting PYTHONWARNINGS=default in the environment. 在不太理想的情况下,可以通过将-Wd传递给Python解释器(这是-W default的缩写)或在环境中设置PYTHONWARNINGS=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 can change what argument is passed to -W (e.g. -W error). 要更改对遇到的警告采取的操作,可以更改传递给-W的参数(例如-W error)。See the -W flag for more details on what is possible.请参阅-W标志以了解有关可能的更多信息。

Available Functions可用功能

warnings.warn(message, category=None, stacklevel=1, source=None)

Issue a warning, or maybe ignore it or raise an exception. 发出警告,或者忽略它或引发异常。The category argument, if given, must be a warning category class; it defaults to UserWarning. category参数(如果给定)必须是警告类别类;它默认为UserWarningAlternatively, message can be a Warning instance, in which case category will be ignored and message.__class__ will be used. 或者,message可以是Warning实例,在这种情况下,将忽略category,并将使用message.__class__In this case, the message text will be str(message). 在这种情况下,消息文本将是str(message)This function raises an exception if the particular warning issued is changed into an error by the warnings filter. 如果警告筛选器将发出的特定警告更改为错误,则此函数会引发异常。The stacklevel argument can be used by wrapper functions written in Python, like this:stacklevel参数可以由Python编写的包装器函数使用,如下所示:

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

This makes the warning refer to deprecation()’s caller, rather than to the source of deprecation() itself (since the latter would defeat the purpose of the warning message).这使得警告指向deposition()的调用方,而不是depositation()本身的源(因为后者会破坏警告消息的目的)。

source, if supplied, is the destroyed object which emitted a ResourceWarning.如果提供了sourcesource是发出ResourceWarning的已销毁对象。

Changed in version 3.6:版本3.6中更改: Added source parameter.添加了source参数。

warnings.warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None)

This is a low-level interface to the functionality of warn(), passing in explicitly the message, category, filename and line number, and optionally the module name and the registry (which should be the __warningregistry__ dictionary of the module). 这是warn()功能的低级接口,显式传递消息、类别、文件名和行号,以及可选的模块名称和注册表(应该是模块的__warningregistry__目录)。The module name defaults to the filename with .py stripped; if no registry is passed, the warning is never suppressed. 模块名默认为去掉.py的文件名;如果没有传递注册表,则警告永远不会被抑制。message must be a string and category a subclass of Warning or message may be a Warning instance, in which case category will be ignored.message必须是字符串,并且categoryWarning的子类,或者message可以是Warning实例,在这种情况下,category将被忽略。

module_globals, if supplied, should be the global namespace in use by the code for which the warning is issued. 如果提供module_globalsmodule_globals应该是发出警告的代码所使用的全局命名空间。(This argument is used to support displaying source for modules found in zipfiles or other non-filesystem import sources).(此参数用于支持显示zip文件或其他非文件系统导入源中的模块的源代码)。

source, if supplied, is the destroyed object which emitted a ResourceWarning.如果提供sourcesource是发出ResourceWarning的已销毁对象。

Changed in version 3.6:版本3.6中更改: Add the source parameter.添加source参数。

warnings.showwarning(message, category, filename, lineno, file=None, line=None)

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. 默认实现调用formatwarning(message, category, filename, lineno, line),并将生成的字符串写入file,默认为sys.stderrYou may replace this function with any callable by assigning to warnings.showwarning. 您可以通过指定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.line是要包含在警告消息中的源代码行;如果未提供lineshowwarning()将尝试读取filenamelineno指定的行。

warnings.formatwarning(message, category, filename, lineno, line=None)

Format a warning the standard way. 以标准方式设置警告格式。This returns a string which may contain embedded newlines and ends in a newline. 这将返回一个字符串,该字符串可能包含嵌入的换行符并以换行符结尾。line is a line of source code to be included in the warning message; if line is not supplied, formatwarning() will try to read the line specified by filename and lineno.line是要包含在警告消息中的源代码行;如果没有提供lineformatwarning()将尝试读取filenamelineno指定的行。

warnings.filterwarnings(action, message='', category=Warning, module='', lineno=0, append=False)

Insert an entry into the list of warnings filter specifications. 警告筛选器规格列表中插入条目。The entry is inserted at the front by default; if append is true, it is inserted at the end. 默认情况下,条目插入在前面;如果appendtrue,则在末尾插入。This checks the types of the arguments, compiles the message and module regular expressions, and inserts them as a tuple in the list of warnings filters. 这将检查参数的类型,编译messagemodule正则表达式,并将它们作为元组插入警告筛选器列表中。Entries closer to the front of the list override entries later in the list, if both match a particular warning. 如果两个条目都与特定警告相匹配,则靠近列表前面的条目将覆盖列表后面的条目。Omitted arguments default to a value that matches everything.省略的参数默认为匹配所有内容的值。

warnings.simplefilter(action, category=Warning, lineno=0, append=False)

Insert a simple entry into the list of warnings filter specifications. 警告筛选器规格列表中插入一个简单条目。The meaning of the function parameters is as for filterwarnings(), but regular expressions are not needed as the filter inserted always matches any message in any module as long as the category and line number match.函数参数的含义与filterwarnings()相同,但不需要正则表达式,因为插入的筛选器始终匹配任何模块中的任何消息,只要类别和行号匹配即可。

warnings.resetwarnings()

Reset the warnings filter. 重置警告筛选器。This discards the effect of all previous calls to filterwarnings(), including that of the -W command line options and calls to simplefilter().这将放弃之前对filterwarnings()的所有调用的效果,包括-W命令行选项和对simplefilter()的调用。

Available Context Managers可用上下文管理器

classwarnings.catch_warnings(*, record=False, module=None)

A context manager that copies and, upon exit, restores the warnings filter and the showwarning() function. 一个上下文管理器,在退出时复制并恢复警告筛选器和showwarning()函数。If the record argument is False (the default) the context manager returns None on entry. 如果record参数为False(默认值),则上下文管理器在输入时返回NoneIf record is True, a list is returned that is progressively populated with objects as seen by a custom showwarning() function (which also suppresses output to sys.stdout). 如果recordTrue,则返回一个列表,该列表将逐步填充对象,如自定义showwarning()函数所示(这也会抑制输出到sys.stdout)。Each object in the list has attributes with the same names as the arguments to showwarning().列表中的每个对象都具有与showwarning()参数同名的属性。

The module argument takes a module that will be used instead of the module returned when you import warnings whose filter will be protected. module参数采用将使用的模块,而不是在导入其筛选器将受到保护的warnings时返回的模块。This argument exists primarily for testing the warnings module itself.此参数主要用于测试warnings模块本身。

Note

The catch_warnings manager works by replacing and then later restoring the module’s showwarning() function and internal list of filter specifications. catch_warnings管理器的工作方式是替换模块的showwarning()函数和筛选器规范的内部列表,然后再恢复。This means the context manager is modifying global state and therefore is not thread-safe.这意味着上下文管理器正在修改全局状态,因此不是线程安全的。