Browse Source

bpo-36829: Document test.support.catch_unraisable_exception() (GH-13554)

catch_unraisable_exception() now also removes its 'unraisable'
attribute at the context manager exit.
pull/13563/head
Victor Stinner 7 years ago
committed by GitHub
parent
commit
6dbbe748e1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      Doc/library/test.rst
  2. 8
      Lib/test/support/__init__.py
  3. 20
      Lib/test/test_io.py

20
Doc/library/test.rst

@ -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

8
Lib/test/support/__init__.py

@ -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

20
Lib/test/test_io.py

@ -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…
Cancel
Save