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

Если запустить этот код, он выведет:

Пошаговый разбор
- Определяем собственный класс исключения
ParseError, унаследованный отException. - В блоке
tryвыполняетсяraise ParseError('parsed') from ValueError('raw').
- Это создаёт новое исключение ParseError с сообщением 'parsed'.
- Ключевое — from ValueError('raw') явно связывает исходное исключение ValueError('raw') как причину текущего.
- Внутреннее св-во ParseError.__cause__ будет указывать на объект ValueError('raw').
- В блоке
except ParseError as eмы ловим возникшийParseErrorи обращаемся кe.__cause__.
- type(e.__cause__).__name__ даёт имя класса причины: ValueError.
- e.__cause__.args[0] — первое (и в данном случае единственное) аргумент-сообщение: 'raw'.
Почему остальные варианты неверны (кратко)
- Нельзя получить
ParseError parsed— это бы означало, что мы печатаем имя типа текущего исключения и его сообщение. В примере печатаются имя типа причины и её сообщение. None rawне подходит, потому что__cause__неNone: он установлен черезfrom. (Если бы использовалиfrom None, тогда__cause__стал быNone.)ValueError parsedневерно, потому что сообщение, связанное с причиной, —'raw', а не'parsed'.
Дополнения: __cause__ vs __context__ и suppress
__cause__— устанавливается явно черезraise NewExc from OldExc.__context__— Python автоматически сохраняет предыдущее исключение в__context__, если новое возбуждается в обработчике, но не использовалась конструкцияfrom.from None— подавляет автоматическую цепочку и приводит к тому, что__cause__будетNone, а__context__при показе трассировки может быть скрыт.
Примеры для сравнения:


Вывод
Использование raise ... from ... явно связывает новое исключение с причиной, сохраняя исходное исключение в атрибуте __cause__. В рассматриваемом примере это даёт вывод имени типа причины ValueError и её сообщения raw. Такая явная цепочка полезна для понятных трассировок ошибок и передачи контекста при обработке исключений.