如何抑制这些来自 aiohttp 的虚假警告?

vau*_*tah 4 python python-asyncio aiohttp

我有一些代码可以使用asyncio和向远程站点发出请求aiohttp

import aiohttp, asyncio

async def f():
    session = aiohttp.ClientSession()
    async with session.get('https://httpbin.org/get') as response:
        pass

asyncio.run(f())
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它会产生

Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f56796b3d68>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7f56793836a8>, 0.0)]']
connector: <aiohttp.connector.TCPConnector object at 0x7f56796b3f98>
Run Code Online (Sandbox Code Playgroud)

现在,不推荐我提出请求的方式(出于各种原因),这就是我收到这些消息的原因。但是,他们肯定不会阻止我,所以我只想再也见不到他们。

我合理地认为它们是正常的警告,并尝试通过-Wignore命令行选项禁用它们,以及将以下代码放在脚本的开头

import warnings
warnings.filterwarnings('ignore')
Run Code Online (Sandbox Code Playgroud)

但消息不断出现。怎么会?我怎样才能压制他们?

vau*_*tah 5

事实证明,aiohttp 不仅使用该文本发出正常警告,而且在非异常调用期间使用相同的消息调用循环的异常__del__处理程序。

来源ClientSession

def __del__(self, _warnings: Any=warnings) -> None:
    if self._protocol is not None:
        ...
        _warnings.warn('Unclosed connection {!r}'.format(self),
                       ResourceWarning,
                       **kwargs)
        ...
        context = {'client_connection': self,
                   'message': 'Unclosed connection'}
        ...
        self._loop.call_exception_handler(context) # <---
Run Code Online (Sandbox Code Playgroud)

因此,如果您只想抑制来自aiohttp通过循环的异常处理程序发出的警告,则必须

替换循环的默认异常处理程序

例如,使用无操作函数:

async def f():
    asyncio.get_running_loop().set_exception_handler(lambda loop, context: None)
    ...

# No output
Run Code Online (Sandbox Code Playgroud)

或者

更改整个asyncio模块的日志记录级别

由于循环的默认异常处理程序会使用级别记录异常消息logging.ERROR,因此您必须将级别设置为logging.CRITICAL

import logging

async def f():
    logging.getLogger('asyncio').setLevel(logging.CRITICAL)
    ...

# No output
Run Code Online (Sandbox Code Playgroud)