python -We ResourceWarning not erroring

Question:

If I take a simple test script like this, which results in ResourceWarning:

import asyncio
import aiohttp

async def main():
    client = aiohttp.ClientSession()
    await client.get("https://google.com")

asyncio.run(main())

Run it with python -bb -We -X dev test.py.

I’m expecting the ResourceWarning to error and result in a non-0 exit code.

Actual result:

Exception ignored in: <function ClientSession.__del__ at 0x7f397e04beb0>
Traceback (most recent call last):
  File "/home/s/.local/lib/python3.8/site-packages/aiohttp/client.py", line 342, in __del__
    _warnings.warn(
ResourceWarning: Unclosed client session <aiohttp.client.ClientSession object at 0x7f397dfce4b0>
Exception ignored in: <function BaseConnector.__del__ at 0x7f397e0b6eb0>
Traceback (most recent call last):
  File "/home/s/.local/lib/python3.8/site-packages/aiohttp/connector.py", line 281, in __del__
    _warnings.warn(f"Unclosed connector {self!r}", ResourceWarning, **kwargs)
ResourceWarning: Unclosed connector <aiohttp.connector.TCPConnector object at 0x7f397dfce690>
Exception ignored in: <socket.socket fd=7, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.1.18', 45750), raddr=('172.217.169.4', 443)>
ResourceWarning: unclosed <socket.socket fd=7, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.1.18', 45750), raddr=('172.217.169.4', 443)>
Exception ignored in: <function _SelectorTransport.__del__ at 0x7f397e8264b0>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/selector_events.py", line 696, in __del__
    _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
ResourceWarning: unclosed transport <_SelectorSocketTransport fd=7>
Exception ignored in: <function _SelectorTransport.__del__ at 0x7f397e8264b0>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/selector_events.py", line 696, in __del__
    _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
ResourceWarning: unclosed transport <_SelectorSocketTransport fd=6>
Exception ignored in: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.1.18', 42986), raddr=('142.250.187.206', 443)>
ResourceWarning: unclosed <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.1.18', 42986), raddr=('142.250.187.206', 443)>

0 exit code indicating success.

How do I ensure the program actually fails on a warning?

Asked By: Sam Bull

||

Answers:

-We makes the interpreter raise an exception instead of a warning. However, within the __del__ function no exception can be raised. Instead, such exceptions are printed to the stderr and the execution continues. This behavior can be overridden via sys.unraisablehook.

Here’s a modified version of the code that will return non-zero exit code:

import aiohttp
import asyncio
import os
import sys


def custom_hook(args):
    os._exit(7)


async def main():
    client = aiohttp.ClientSession()
    await client.get("https://google.com")


sys.unraisablehook = custom_hook
asyncio.run(main())

Notice that instead of sys.exit() I use os._exit(). That’s because sys.exit() raises SystemExit exception which is a bad idea in our case.

Answered By: Alex
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.