MCPcopy Create free account
hub / github.com/pytest-dev/pytest / catch_unraisable_exception

Class catch_unraisable_exception

src/_pytest/unraisableexception.py:15–59  ·  view source on GitHub ↗

Context manager catching unraisable exception using sys.unraisablehook. Storing the exception value (cm.unraisable.exc_value) creates a reference cycle. The reference cycle is broken explicitly when the context manager exits. Storing the object (cm.unraisable.object) can resurrect

Source from the content-addressed store, hash-verified

13
14# Copied from cpython/Lib/test/support/__init__.py, with modifications.
15class catch_unraisable_exception:
16 """Context manager catching unraisable exception using sys.unraisablehook.
17
18 Storing the exception value (cm.unraisable.exc_value) creates a reference
19 cycle. The reference cycle is broken explicitly when the context manager
20 exits.
21
22 Storing the object (cm.unraisable.object) can resurrect it if it is set to
23 an object which is being finalized. Exiting the context manager clears the
24 stored object.
25
26 Usage:
27 with catch_unraisable_exception() as cm:
28 # code creating an "unraisable exception"
29 ...
30 # check the unraisable exception: use cm.unraisable
31 ...
32 # cm.unraisable attribute no longer exists at this point
33 # (to break a reference cycle)
34 """
35
36 def __init__(self) -> None:
37 self.unraisable: Optional["sys.UnraisableHookArgs"] = None
38 self._old_hook: Optional[Callable[["sys.UnraisableHookArgs"], Any]] = None
39
40 def _hook(self, unraisable: "sys.UnraisableHookArgs") -> None:
41 # Storing unraisable.object can resurrect an object which is being
42 # finalized. Storing unraisable.exc_value creates a reference cycle.
43 self.unraisable = unraisable
44
45 def __enter__(self) -> "catch_unraisable_exception":
46 self._old_hook = sys.unraisablehook
47 sys.unraisablehook = self._hook
48 return self
49
50 def __exit__(
51 self,
52 exc_type: Optional[Type[BaseException]],
53 exc_val: Optional[BaseException],
54 exc_tb: Optional[TracebackType],
55 ) -> None:
56 assert self._old_hook is not None
57 sys.unraisablehook = self._old_hook
58 self._old_hook = None
59 del self.unraisable
60
61
62def unraisable_exception_runtest_hook() -> Generator[None, None, None]:

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected