gh-103791: handle `BaseExceptionGroup` in `contextlib.suppress()` (#111910)

This commit is contained in:
Zac Hatfield-Dodds 2023-11-10 08:32:36 -05:00 committed by GitHub
parent 64fea3211d
commit d61313bdb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 4 deletions

View File

@ -304,15 +304,15 @@ Functions and classes provided:
This context manager is :ref:`reentrant <reentrant-cms>`.
If the code within the :keyword:`!with` block raises an
:exc:`ExceptionGroup`, suppressed exceptions are removed from the
If the code within the :keyword:`!with` block raises a
:exc:`BaseExceptionGroup`, suppressed exceptions are removed from the
group. If any exceptions in the group are not suppressed, a group containing them is re-raised.
.. versionadded:: 3.4
.. versionchanged:: 3.12
``suppress`` now supports suppressing exceptions raised as
part of an :exc:`ExceptionGroup`.
part of an :exc:`BaseExceptionGroup`.
.. function:: redirect_stdout(new_target)

View File

@ -461,7 +461,7 @@ class suppress(AbstractContextManager):
return
if issubclass(exctype, self._exceptions):
return True
if issubclass(exctype, ExceptionGroup):
if issubclass(exctype, BaseExceptionGroup):
match, rest = excinst.split(self._exceptions)
if rest is None:
return True

View File

@ -1297,6 +1297,24 @@ class TestSuppress(ExceptionIsLikeMixin, unittest.TestCase):
[KeyError("ke1"), KeyError("ke2")],
),
)
# Check handling of BaseExceptionGroup, using GeneratorExit so that
# we don't accidentally discard a ctrl-c with KeyboardInterrupt.
with suppress(GeneratorExit):
raise BaseExceptionGroup("message", [GeneratorExit()])
# If we raise a BaseException group, we can still suppress parts
with self.assertRaises(BaseExceptionGroup) as eg1:
with suppress(KeyError):
raise BaseExceptionGroup("message", [GeneratorExit("g"), KeyError("k")])
self.assertExceptionIsLike(
eg1.exception, BaseExceptionGroup("message", [GeneratorExit("g")]),
)
# If we suppress all the leaf BaseExceptions, we get a non-base ExceptionGroup
with self.assertRaises(ExceptionGroup) as eg1:
with suppress(GeneratorExit):
raise BaseExceptionGroup("message", [GeneratorExit("g"), KeyError("k")])
self.assertExceptionIsLike(
eg1.exception, ExceptionGroup("message", [KeyError("k")]),
)
class TestChdir(unittest.TestCase):

View File

@ -0,0 +1,3 @@
:class:`contextlib.suppress` now supports suppressing exceptions raised as
part of a :exc:`BaseExceptionGroup`, in addition to the recent support for
:exc:`ExceptionGroup`.