跳转到主要内容

更灵活的警告模块。

项目描述

warn

更好的警告。

查看完整 文档

Python标准 警告模块 非常好,但我认为它被低估了;尽管它缺少一些功能;特别是它只允许根据触发/调用弃用函数的代码进行过滤,但没有根据发出警告的模块进行过滤的能力。

这是尝试解决这个问题。

明确优于暗示

from warn import patch
patch()

# use the warning module as usual

尽管现在 warnings.filterwarning 函数已经增加了 emodule 关键字参数,可以根据发出警告的模块进行过滤;例如

import warnings
warnings.filter('default', category=DeprecationWarnings, emodule='matplotlib\.pyplot.*')

现在默认显示来自 matplotlib.pyplot 和其子模块的所有警告,无论您是否直接触发它们,通过pandas,seaborn,您自己的代码等。

警告发出者,警告调用者。

Python警告是一段相对简单但非常强大的代码,一旦您学会了如何使用它,它在正确手中就非常强大。

它允许您事后确定是否希望特定的代码块触发异常,向用户显示消息或简单地什么也不做。

很难用一段简单的代码展示警告的全部威力,但在大型代码库中,一旦您开始使用多层依赖,节约地使用警告,尤其是 DeprecationWarning,可以产生很大的影响。

调用者,与发出者

让我们先澄清一些术语,以区分警告“调用者”和警告“发出者”

# file emitter.py

def public_api(param1, deprecated_parameter=None)::

    if deprecated_parameter:
        return _deprecated_function(param1, deprecated_parameter):
    else:
        return normal_buisnell_logic(param1)


def _deprecated_function(param1, deprecated_parameter):
    import warningsA
    # warning emitted here
    warnings.warn('using `deprecated_parameter` is deprecated ',
            DeprecationWarning,
            stacklevel=3)
# file caller.py
from emitter import public_api
public_api(1, True)  # warning triggered here.

您现在可以做一些像这样的事情

from warn import path
patch()

import warnings
warnings.filter('default', category=DeprecationWarnings, emodule='emitter.*')
import emitter
emitter.bar() # will log the warning !

请将测试套件中的此内容更改为“错误”,并通过所有依赖项进行过滤!

Python内置模块允许您通过调用者过滤警告(假设发射者已正确设置stacklevel选项,这并不总是明显)。当您正在开发调用者时,这非常有用;但是当您正在开发发射者时,作用就不大了。

调用者实际上可能有多个底层库可以触发警告,或者开发者可能只关心发射者警告的一部分。

许多库通过子类化Warning来绕过这个限制;两个例子是Matplotlibsympy,以便有选择地启用它们。然而,这仅提供了一种粗略的过滤警告方式,并且需要知道警告在哪里定义,才能导入和过滤它们。

由于Python默认会过滤掉弃用警告,这也迫使您要么继承UserWarning(matplotlib的选择),这消除了Python提供的DeprecationWarning的语义意义,要么在导入时在警告过滤模块中注入自定义过滤器(Sympy的选择),这可能导致意外行为。

Python 2上的可用性

我不知道它是否在Python 2上工作;我实在没有时间去调查;我并不特别关心;但如果需要,您可以随时发送一个PR以添加支持,我很乐意将其合并。

限制

这不能在以下包上工作

  • 在调用patch()之前获取并保留对warnings.warn的引用;也就是说,形式如下:from warnings import warn

  • 不能在C扩展(即不会在numpy上过滤)上工作;上述两种情况都可通过汇编修补来实现,但我对此不太舒服。

糟糕的部分

由于警告过滤器必须是具有特定类型的5个元组,因此它通过在过滤器列表中放入虚拟实例,并使用这些实例作为代理查找真实过滤器键的键来实现。所以最坏的情况是,您用这个模块插入的过滤器将没有任何效果。但是,如果您使用这个,尤其是如果您的代码库触发了大量警告,您将承担性能损失。

获取上游

我非常希望能够得到反馈,并有一个更好的API来处理CPython级别的警告,以便提供自定义过滤器,和自定义过滤器函数。

轶事

良好的弃用警告。

一个好的警告,特别是弃用警告,非常有帮助,并且可以改变API的采用率。以下是一个虚构的例子

>>> import warnings

>>> warnings.simplefilter('default')

>>> from quezetraste import frobulate, constribule

>>> frobulate('HI', 3)
DeprecationWarning: The 'frobulate' function is deprecated.

>>> contribule('Hi', 3)

DeprecationWarning: The 'constribule(message, recipient_id)' function of the
                    'quezetraste' package is deprecated since version 7.3. It
                    haz been replaced by 'Recipient(id).send(message)' which
                    was available since 7.2. See http://url.to/documentation/#1337

将弃用警告转换为测试套件中的错误!

至少使它们可见;最好是在修复了一个弃用警告后,将这个特定的警告转换为错误,以防止其再次出现。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

此版本没有提供源分发文件。请参阅生成分发存档的教程

构建分发

warn-0.1.0-py2.py3-none-any.whl (23.6 kB 查看哈希值)

上传时间 Python 2 Python 3

支持者