bpo-36829: Document test.support.catch_unraisable_exception() (GH-13554)
catch_unraisable_exception() now also removes its 'unraisable' attribute at the context manager exit.
This commit is contained in:
parent
a9f05d69cc
commit
6dbbe748e1
|
@ -1081,6 +1081,26 @@ The :mod:`test.support` module defines the following functions:
|
|||
:exc:`PermissionError` is raised.
|
||||
|
||||
|
||||
.. function:: catch_unraisable_exception()
|
||||
|
||||
Context manager catching unraisable exception using
|
||||
:func:`sys.unraisablehook`.
|
||||
|
||||
Usage::
|
||||
|
||||
with support.catch_unraisable_exception() as cm:
|
||||
# code creating an "unraisable exception"
|
||||
...
|
||||
|
||||
# check the unraisable exception: use cm.unraisable
|
||||
...
|
||||
|
||||
# cm.unraisable attribute no longer exists at this point
|
||||
# (to break a reference cycle)
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
.. function:: find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)
|
||||
|
||||
Returns an unused port that should be suitable for binding. This is
|
||||
|
|
|
@ -3043,12 +3043,14 @@ class catch_unraisable_exception:
|
|||
Usage:
|
||||
|
||||
with support.catch_unraisable_exception() as cm:
|
||||
# code creating an "unraisable exception"
|
||||
...
|
||||
|
||||
# check the expected unraisable exception: use cm.unraisable
|
||||
# check the unraisable exception: use cm.unraisable
|
||||
...
|
||||
|
||||
# cm.unraisable is None here (to break a reference cycle)
|
||||
# cm.unraisable attribute no longer exists at this point
|
||||
# (to break a reference cycle)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
@ -3065,5 +3067,5 @@ class catch_unraisable_exception:
|
|||
|
||||
def __exit__(self, *exc_info):
|
||||
# Clear the unraisable exception to explicitly break a reference cycle
|
||||
self.unraisable = None
|
||||
del self.unraisable
|
||||
sys.unraisablehook = self._old_hook
|
||||
|
|
|
@ -1098,18 +1098,14 @@ class CommonBufferedTests:
|
|||
# Test that the exception state is not modified by a destructor,
|
||||
# even if close() fails.
|
||||
rawio = self.CloseFailureIO()
|
||||
try:
|
||||
with support.catch_unraisable_exception() as cm:
|
||||
with self.assertRaises(AttributeError):
|
||||
self.tp(rawio).xyzzy
|
||||
with support.catch_unraisable_exception() as cm:
|
||||
with self.assertRaises(AttributeError):
|
||||
self.tp(rawio).xyzzy
|
||||
|
||||
if not IOBASE_EMITS_UNRAISABLE:
|
||||
self.assertIsNone(cm.unraisable)
|
||||
elif cm.unraisable is not None:
|
||||
self.assertEqual(cm.unraisable.exc_type, OSError)
|
||||
finally:
|
||||
# Explicitly break reference cycle
|
||||
cm = None
|
||||
|
||||
def test_repr(self):
|
||||
raw = self.MockRawIO()
|
||||
|
@ -2854,18 +2850,14 @@ class TextIOWrapperTest(unittest.TestCase):
|
|||
# Test that the exception state is not modified by a destructor,
|
||||
# even if close() fails.
|
||||
rawio = self.CloseFailureIO()
|
||||
try:
|
||||
with support.catch_unraisable_exception() as cm:
|
||||
with self.assertRaises(AttributeError):
|
||||
self.TextIOWrapper(rawio).xyzzy
|
||||
with support.catch_unraisable_exception() as cm:
|
||||
with self.assertRaises(AttributeError):
|
||||
self.TextIOWrapper(rawio).xyzzy
|
||||
|
||||
if not IOBASE_EMITS_UNRAISABLE:
|
||||
self.assertIsNone(cm.unraisable)
|
||||
elif cm.unraisable is not None:
|
||||
self.assertEqual(cm.unraisable.exc_type, OSError)
|
||||
finally:
|
||||
# Explicitly break reference cycle
|
||||
cm = None
|
||||
|
||||
# Systematic tests of the text I/O API
|
||||
|
||||
|
|
Loading…
Reference in New Issue