aiohttp icon indicating copy to clipboard operation
aiohttp copied to clipboard

Right way of keeping module from destruction

Open vinnik-dmitry07 opened this issue 2 months ago • 5 comments

To reproduce:

# Old example, look below for a new one

What do these changes do?

Fixes Exception ignored in sys.unraisablehook:

You should store the function not the module.

Are there changes in behavior for the user?

No.

No.

Is it a substantial burden for the maintainers to support this?

No.

No.

vinnik-dmitry07 avatar Oct 24 '25 23:10 vinnik-dmitry07

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 98.73%. Comparing base (6fabae5) to head (0ba123d). :white_check_mark: All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #11715   +/-   ##
=======================================
  Coverage   98.73%   98.73%           
=======================================
  Files         127      127           
  Lines       43558    43558           
  Branches     2320     2320           
=======================================
+ Hits        43007    43008    +1     
  Misses        390      390           
+ Partials      161      160    -1     
Flag Coverage Δ
CI-GHA 98.61% <100.00%> (+<0.01%) :arrow_up:
OS-Linux 98.34% <100.00%> (ø)
OS-Windows 96.67% <100.00%> (+<0.01%) :arrow_up:
OS-macOS 97.55% <100.00%> (-0.01%) :arrow_down:
Py-3.10.11 97.10% <100.00%> (ø)
Py-3.10.18 97.61% <100.00%> (+0.01%) :arrow_up:
Py-3.11.13 97.80% <100.00%> (ø)
Py-3.11.9 97.31% <100.00%> (ø)
Py-3.12.10 97.41% <100.00%> (ø)
Py-3.12.11 97.92% <100.00%> (+<0.01%) :arrow_up:
Py-3.13.7 97.91% <100.00%> (-0.01%) :arrow_down:
Py-3.13.8 ?
Py-3.13.9 97.39% <100.00%> (+1.14%) :arrow_up:
Py-3.14.0 98.12% <100.00%> (+<0.01%) :arrow_up:
Py-3.14.0t 97.18% <100.00%> (-0.01%) :arrow_down:
Py-pypy3.10.16-7.3.19 82.54% <50.00%> (-5.43%) :arrow_down:
VM-macos 97.55% <100.00%> (-0.01%) :arrow_down:
VM-ubuntu 98.34% <100.00%> (ø)
VM-windows 96.67% <100.00%> (+<0.01%) :arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Oct 24 '25 23:10 codecov[bot]

CodSpeed Performance Report

Merging #11715 will not alter performance

Comparing vinnik-dmitry07:patch-3 (0ba123d) with master (6fabae5)

Summary

✅ 59 untouched

codspeed-hq[bot] avatar Oct 24 '25 23:10 codspeed-hq[bot]

Fixes Exception ignored in sys.unraisablehook:

What exception? (your reproducer is not complete, and doesn't seem to reproduce on my machine)

Dreamsorcerer avatar Oct 25 '25 10:10 Dreamsorcerer

I had to look up why this was used in the first place. For anyone else, relevant part of the docs:

del() can be executed during interpreter shutdown. As a consequence, the global variables it needs to access (including other modules) may already have been deleted or set to None. Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the del() method is called.

Dreamsorcerer avatar Oct 25 '25 11:10 Dreamsorcerer

image

import sys
import asyncio
import aiohttp
import traceback


def _unraisable_hook(unraisable, format_exception=traceback.format_exception):
    tb_lines = format_exception(unraisable.exc_type, unraisable.exc_value, unraisable.exc_traceback)
    tb_str = ''.join(tb_lines)
    print(
        tb_str,
        'Unraisable exception error from %r',
        getattr(unraisable, 'object', None),
        (unraisable.exc_type, unraisable.exc_value, unraisable.exc_traceback),
        f'{unraisable.exc_type.__name__}: {unraisable.exc_value}'
    )


sys.unraisablehook = _unraisable_hook

class A:
    def __init__(self):
        asyncio.get_event_loop().run_until_complete(self.a())
        raise

    async def a(self):
        aiohttp_session = aiohttp.ClientSession()
        await aiohttp_session.request(
            method='get',
            url='https://google.com',
        )


A()

vinnik-dmitry07 avatar Oct 28 '25 01:10 vinnik-dmitry07