如何过滤导入过程中发生的 DeprecationWarnings?

How to filter DeprecationWarnings that happen during importing?

我们正在将我们的应用程序从 Django 1.6 更新到 1.7。

我们看到了很多这样的消息:RemovedInDjango18Warning

有没有办法过滤它们?它们在导入过程中发出。

我们尝试了 warnings.filterwarnings('ignore', '...'),但在我们调用 warnings.filterwarnings() 之前发出了警告。

如何过滤导入过程中出现的这些警告?

快速修复

要仅在 运行 manage.py 时将其静音,请在 import sys 之后添加这些行:

# ...
import sys

if not sys.warnoptions:
    sys.warnoptions += [None]

# ...

如果您还想从您的 WSGI 服务器(即 Apache)中将其静音,请更新 your_project/wsgi.py 并在 import os 之后添加以下行:

# ...
import os
import sys

if not sys.warnoptions:
    sys.warnoptions += [None]

# ...

说明

之所以有效,是因为 django.utils.log.configure_logging() 处理它的方式:

def configure_logging(logging_config, logging_settings):
    if not sys.warnoptions:
        # Route warnings through python logging
        logging.captureWarnings(True)
        # RemovedInNextVersionWarning is a subclass of DeprecationWarning which
        # is hidden by default, hence we force the "default" behavior
        warnings.simplefilter("default", RemovedInNextVersionWarning)
    # ...

作为 django.setup() 的一部分,它在启动过程的早期被故意调用,这解释了为什么在您能够在堆栈中进一步消除它们之前发出错误。

sys.warnoptions 添加新元素会强制其计算为 True,绕过逻辑。这是无害的,因为它在被 warnings 模块加载时是 only used during python startup

RemovedInNextVersionWarning 只是 RemovedInDjango18Warning in Django 1.7. It is set to RemovedInDjango19Warning in 1.8 的别名,对于未来的版本依此类推——此代码应该是此类 DeprecationWarning.

的未来证明

命令行方法

请注意,sys.warnoptions通常是在python启动期间根据调用python时的-W argument设置的。因此,使用开发服务器时让警告静音的一种简单方法是 python -W123 manage.py runserver。这不需要修改文件,但会在启动时产生一个无害的警告,因为 123 只是一个占位符而不是有效的警告操作。

另一种方法是 python -Wi::DeprecationWarning manage.py runserver,尽管这将忽略 ALL DeprecationWarning,包括可能感兴趣的 RemovedInDjango18Warning