如何使用 warnings.filterwarnings 抑制第三方警告

发布于 2024-09-27 05:08:18 字数 1343 浏览 7 评论 0原文

我在 python 代码中使用 Paramiko(用于 sftp)。除了每次导入或调用 paramiko 函数之外,一切都工作正常。将显示此警告:

C:\Python26\lib\site-packages\Crypto\Util\randpool.py:40: RandomPool_Deprecation
Warning: This application uses RandomPool, which is BROKEN in older releases.  S
ee http://www.pycrypto.org/randpool-broken
  RandomPool_DeprecationWarning)

我知道这与 Paramiko 正在使用 PyCrypto 的某些已弃用功能有关。

我的问题是,有没有办法以编程方式抑制此警告? 我已经尝试过这个:

warnings.filterwarnings(action='ignore', \
category=DeprecationWarning, module='paramiko')

甚至这个:

warnings.filterwarnings(action='ignore', \
category=DeprecationWarning, module='randpool')

在“import paramiko”语句之前和特定于 paramiko 的函数调用之前,但没有任何效果。不管怎样,这个警告都会不断出现。 如果有帮助,这里是第三方库中打印警告的代码:

在 randpool.py 中:

from Crypto.pct_warnings import RandomPool_DeprecationWarning
import Crypto.Random
import warnings

class RandomPool:
    """Deprecated.  Use Random.new() instead.

    See http://www.pycrypto.org/randpool-broken
    """
    def __init__(self, numbytes = 160, cipher=None, hash=None, file=None):
        warnings.warn("This application uses RandomPool, which is BROKEN in older releases.  See http://www.pycrypto.org/randpool-broken",
            RandomPool_DeprecationWarning)

如果您知道解决此问题的方法,请帮我关闭此警告。

I am using Paramiko in my python code (for sftp). Everything works fine except that everytime I import or call a paramiko function. This warning would show up:

C:\Python26\lib\site-packages\Crypto\Util\randpool.py:40: RandomPool_Deprecation
Warning: This application uses RandomPool, which is BROKEN in older releases.  S
ee http://www.pycrypto.org/randpool-broken
  RandomPool_DeprecationWarning)

I know that this has to do with the fact that Paramiko is using some Deprecated functionalities of PyCrypto.

My question is, is there a way to suppress this warning programmatically ?
I have tried this:

warnings.filterwarnings(action='ignore', \
category=DeprecationWarning, module='paramiko')

and even this:

warnings.filterwarnings(action='ignore', \
category=DeprecationWarning, module='randpool')

before 'import paramiko' statement and before paramiko-specific function calls, but nothing works. This warning keeps showing up no matter what.
If it helps, here's the code in the third party library that prints the warning:

in randpool.py:

from Crypto.pct_warnings import RandomPool_DeprecationWarning
import Crypto.Random
import warnings

class RandomPool:
    """Deprecated.  Use Random.new() instead.

    See http://www.pycrypto.org/randpool-broken
    """
    def __init__(self, numbytes = 160, cipher=None, hash=None, file=None):
        warnings.warn("This application uses RandomPool, which is BROKEN in older releases.  See http://www.pycrypto.org/randpool-broken",
            RandomPool_DeprecationWarning)

If you know a way around this, please help me shut this warning off.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅笑依然 2024-10-04 05:08:18

最简单的方法是警告模块此处建议的那样:

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    import paramiko

Easiest way would be as the warnings module suggests here:

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    import paramiko
乙白 2024-10-04 05:08:18

warnings.filterwarningsmodule 参数采用区分大小写的正则表达式,该表达式应与完全限定的模块名称匹配,因此

warnings.filterwarnings(
    action='ignore',
    category=DeprecationWarning,
    module=r'.*randpool'
)

warnings.filterwarnings(
    action='ignore',
    category=DeprecationWarning,
    module=r'Crypto\.Utils\.randpool'
)

应该有效。如果由于某种原因 RandomPool_DeprecationWarning 不是 DeprecationWarning 的子类,您可能需要显式编写 RandomPool_DeprecationWarning 而不是 DeprecationWarning

您还可以在调用脚本时通过将 -W 选项传递给解释器来禁用命令行上的警告,如下所示:

$ python -W ignore::RandomPool_DeprecationWarning:Crypto.Utils.randpool: my_script.py

-W 采用格式 < code>action:message:category:module:lineno,这次 module 必须与引发警告的(完全限定)模块名称完全匹配。

请参阅 https://docs.python.org/ 2/library/warnings.html?highlight=warnings#the-warnings-filterhttps://docs.python.org/2/using/cmdline.html#cmdoption-w

The module argument to warnings.filterwarnings takes a case-sensitive regular expression which should match the fully qualified module name, so

warnings.filterwarnings(
    action='ignore',
    category=DeprecationWarning,
    module=r'.*randpool'
)

or

warnings.filterwarnings(
    action='ignore',
    category=DeprecationWarning,
    module=r'Crypto\.Utils\.randpool'
)

should work. You may need to write RandomPool_DeprecationWarning explicitly instead of DeprecationWarning if for some reason RandomPool_DeprecationWarning is not a subclass of DeprecationWarning.

You can also disable the warning on the command line when you invoke the script by passing the -W option to the interpreter like so:

$ python -W ignore::RandomPool_DeprecationWarning:Crypto.Utils.randpool: my_script.py

The -W takes filters in the format action:message:category:module:lineno, where this time module must exactly match the (fully-qualified) module name where the warning is raised.

See https://docs.python.org/2/library/warnings.html?highlight=warnings#the-warnings-filter and https://docs.python.org/2/using/cmdline.html#cmdoption-w

逐鹿 2024-10-04 05:08:18

仅过滤特定警告:

with warnings.catch_warnings():
    warnings.simplefilter('ignore', SpecificWarningObject)

    #do something that raises a Warning

To filter only a specific warning:

with warnings.catch_warnings():
    warnings.simplefilter('ignore', SpecificWarningObject)

    #do something that raises a Warning
琉璃梦幻 2024-10-04 05:08:18

最灵活的方法是结合 warnings.filterwarnings()< /code>(或 warnings.simplefilter( )) 和 警告.catch_warnings() 上下文管理器。通过这种方式,您可以获得 filterwarnings 的灵活性,但过滤仅应用于 with 块内:

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings(
        action='ignore',
        category=SomeWarningClass,
        message='some message')
   
    # Do stuff that causes the warning

请参阅 文档中的警告过滤器,用于描述 filterwarnings 的参数。

完整示例

这是带有自定义警告的完整示例:

import warnings

# Custom warning class for the example
class MyWarning(UserWarning):
    pass

def function_that_issues_warning(num):
    print(num)
    warnings.warn("This is a warning", MyWarning)


with warnings.catch_warnings():
    function_that_issues_warning(1) # issues warning
    warnings.filterwarnings(
        action="ignore", category=MyWarning, message="This is a warning"
    )

    function_that_issues_warning(2) # Warning is filtered
function_that_issues_warning(3) # issues warning

示例输出

1
.\test_warnings.py:10: MyWarning: This is a warning
  warnings.warn("This is a warning", MyWarning)
2
3
.\test_warnings.py:10: MyWarning: This is a warning
  warnings.warn("This is a warning", MyWarning)

The most flexible way is to combine warnings.filterwarnings() (or warnings.simplefilter()) with the warnings.catch_warnings() context manager. This way you ge the flexibility of filterwarnings but the filtering is only applied inside the with block:

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings(
        action='ignore',
        category=SomeWarningClass,
        message='some message')
   
    # Do stuff that causes the warning

See The Warnings Filter in the docs for the descriptions of the arguments for filterwarnings.

Full example

Here is a full example with a custom warning:

import warnings

# Custom warning class for the example
class MyWarning(UserWarning):
    pass

def function_that_issues_warning(num):
    print(num)
    warnings.warn("This is a warning", MyWarning)


with warnings.catch_warnings():
    function_that_issues_warning(1) # issues warning
    warnings.filterwarnings(
        action="ignore", category=MyWarning, message="This is a warning"
    )

    function_that_issues_warning(2) # Warning is filtered
function_that_issues_warning(3) # issues warning

Example output

1
.\test_warnings.py:10: MyWarning: This is a warning
  warnings.warn("This is a warning", MyWarning)
2
3
.\test_warnings.py:10: MyWarning: This is a warning
  warnings.warn("This is a warning", MyWarning)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文