ExceptionGroup(msg, excs)
BaseExceptionGroup(msg, excs)
:Новое в Python 3.11
Изменено в Python 3.12: Когда конструкция
try-except*
обрабатывает всю группуExceptionGroup
и вызывает еще одно исключение, это исключение больше не помещается вExceptionGroup
. Это поведение было изменено в версии 3.11.4. но не задокументировано (Предоставлено Ирит Катриэль.)
Оба типа исключений ExceptionGroup()
и BaseExceptionGroup()
заключают исключения в последовательность excs
. Аргумент msg
должен быть строкой. Разница между этими двумя классами заключается в том, что BaseExceptionGroup
расширяет BaseException
и может обертывать любое исключение, а ExceptionGroup
расширяет Exception
и может обертывать только подклассы Exception
. Этот дизайн таков, что кроме Exception
ловится ExceptionGroup
, но не BaseExceptionGroup
.
Конструктор BaseExceptionGroup
возвращает ExceptionGroup
, а не BaseExceptionGroup
, если все содержащиеся исключения являются экземплярами Exception
, поэтому его можно использовать для автоматического выбора. Конструктор ExceptionGroup
, с другой стороны, вызывает TypeError
, если какое-либо содержащееся исключение не является подклассом Exception
.
BaseExceptionGroup
:.message
:Атрибут .message
- это аргумент msg
для конструктора. Это атрибут только для чтения.
.exceptions
:Атрибут .exceptions
- это Кортеж исключений в последовательности excs
, передаваемой конструктору. Это атрибут только для чтения.
.subgroup(condition)
:Метод .subgroup()
возвращает группу исключений, содержащую только те исключения из текущей группы, которые соответствуют условию condition
, или None
, если результат пуст.
Условие condition
может быть либо функцией, которая принимает исключение и возвращает True
для тех, которые должны быть в подгруппе, либо может быть типом исключения или кортежем типов исключений, который используется для проверки на совпадение с помощью той же проверки, что и используется в предложении исключения.
Структура вложенности текущего исключения сохраняется в результате, как и значения его сообщения, полей __traceback__
, __cause__
, __context__
и __notes__
. Пустые вложенные группы исключаются из результата.
Условие condition
проверяется для всех исключений во вложенной группе исключений, включая группу исключений верхнего уровня и все вложенные группы исключений. Если условие истинно для такой группы исключений, то оно включается в результат полностью.
.split(condition)
:Метод работает подобно .subgroup()
, но возвращает пару (match, rest)
, где match
- это подгруппа (условие), а rest
- оставшаяся несовпадающая часть.
.derive(excs)
:Возвращает группу исключений с тем же сообщением, __traceback__
, __cause__
, __context__
и __notes__
, но заключает исключения в excs
.
Этот метод используется методами .subgroup()
и .split()
. Подкласс должен переопределить его, чтобы .subgroup()
и split()
возвращали экземпляры подкласса, а не ExceptionGroup
.
Методы .subgroup()
и .split()
копируют поля __traceback__
, __cause__
, __context__
и __notes__
из исходной группы исключений в группу, возвращенную методом .derive()
, поэтому эти поля не нужно обновлять с помощью derive()
.
class MyGroup(ExceptionGroup): def derive(self, exc): return MyGroup(self.message, exc) e = MyGroup("eg", [ValueError(1), TypeError(2)]) e.add_note("a note") e.__context__ = Exception("context") e.__cause__ = Exception("cause") try: raise e except Exception as e: exc = e match, rest = exc.split(ValueError) exc, exc.__context__, exc.__cause__, exc.__notes__ # (MyGroup('eg', [ValueError(1), TypeError(2)]), Exception('context'), Exception('cause'), ['a note']) match, match.__context__, match.__cause__, match.__notes__ # (MyGroup('eg', [ValueError(1)]), Exception('context'), Exception('cause'), ['a note']) rest, rest.__context__, rest.__cause__, rest.__notes__ # (MyGroup('eg', [TypeError(2)]), Exception('context'), Exception('cause'), ['a note']) exc.__traceback__ is match.__traceback__ is rest.__traceback__ # True
BaseExceptionGroup
.Обратите внимание, что
BaseExceptionGroup
определяет метод__new__()
, поэтому подклассы, которым нужна другая сигнатура конструктора, должны переопределить ее, а не__init__()
.
В примере определяется подкласс группы исключений, который принимает код выхода exit_code
и создает из него сообщение группы.
class Errors(ExceptionGroup): def __new__(cls, errors, exit_code): self = super().__new__(Errors, f"exit code: {exit_code}", errors) self.exit_code = exit_code return self def derive(self, excs): return Errors(excs, self.exit_code)
Как и ExceptionGroup
, любой подкласс BaseExceptionGroup
, который также является подклассом Exception
, может обертывать только экземпляры Exception
.