Как подавить эти ложные предупреждения от aiohttp? - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть код, который делает запросы к удаленным сайтам, используя 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())

Когда я запускаю его, он выдает

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>

Теперь способ отправки запросов не рекомендуется (по разным причинам), поэтому я получаю эти сообщения. Однако они точно меня не остановят, и поэтому я просто хочу никогда их больше не видеть.

Я обоснованно предположил, что это обычные предупреждения, и попытался отключить их с помощью параметра командной строки -Wignore, а также поместив следующий код в начало сценария

import warnings
warnings.filterwarnings('ignore')

но сообщения продолжали появляться. Как так? Как я могу их подавить?

1 Ответ

0 голосов
/ 04 апреля 2019

Оказывается, 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) # <---

Таким образом, если вы хотите подавить только предупреждения, которые поступают из aiohttp библиотеки и через циклОбработчик исключений, вы должны либо

Заменить обработчик исключений цикла по умолчанию

Например, функцией no-op:

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

# No output

или

Измените уровень ведения журнала для всего модуля asyncio

Поскольку обработчик исключений цикла по умолчанию регистрирует сообщения об исключениях с уровнем logging.ERROR, вам придется установить уровень logging.CRITICAL

import logging

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

# No output
...