Исключения и chaining: как работает raise ... from ... в Python
@python_quizРазберем этот квиз
Коротко: код показывает создание пользовательского исключения с привязкой к исходному через конструкцию raise ... from .... Разберём, что печатает программа и почему.
Код квиза

Что делает raise ... from ...
- Конструкция
raise NewException(...) from OriginalException(...)явно связывает исключениеNewExceptionс причинным исключениемOriginalException. - При этом у нового исключения устанавливается атрибут
__cause__, который ссылается на объект исходного исключения. - Если
fromне используется, но исключение происходит во время обработки другого — Python может заполнить__context__, а__cause__останетсяNone, если явно не задан. - Форматирование трассировки и строки зависит от этих атрибутов, но мы в коде читаем именно
type(e).__name__иtype(e.__cause__).__name__.
Разбор вывода
В блоке except Exception as e: переменная e содержит поднятое исключение — это экземпляр ConfigError. Выражения в print:
type(e).__name__— имя класса текущего исключения, то есть "ConfigError".type(e.__cause__).__name__— имя класса причинного исключения, установленного черезfrom, то есть "FileNotFoundError".
Поэтому строка, которая будет напечатана:

Анализ предложенных вариантов
- Вариант с
ConfigError -> FileNotFoundErrorсовпадает с реальным выводом — т.к.__cause__явно задан черезfrom. ConfigError -> Noneмог бы появиться, если быfromне использовался и__cause__оставался пустым (и при этом__context__не выводился в печати), но в нашем кодеfromесть.FileNotFoundError -> ConfigErrorневерен: текущим исключением являетсяConfigError, а неFileNotFoundError.Exception -> FileNotFoundErrorневерен, потому чтоtype(e).__name__возвращает конкретный класс исключения (ConfigError), а не базовыйException.
Дополнительные замечания
- Атрибуты исключений:
- __cause__ — явно заданная причина через from.
- __context__ — автоматически сохраняет предыдущее исключение, если оно случилось во время обработки другого.
- __suppress_context__ — если установлено в True, подавляет показ __context__ в трассировке при наличии __cause__.
- Для отладки полезно смотреть полную трассировку (
traceback), но для задач с доступом к объектам исключений чтение__cause__даёт точный ответ на связь исключений.
Вывод
Код демонстрирует явную цепочку исключений: новое исключение оборачивает исходное с помощью from, поэтому печатается имя текущего исключения и имя причинного исключения — "ConfigError -> FileNotFoundError".