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)
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
[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):