Проверка контекстного менеджера Python: подавление и замена исключения

Напишите решение на Python и проверьте его на странице.

Другие упражнения по этой теме: Контекстные менеджеры Python: задачи на with, откат и исключения.

Аудит контекстного менеджера

Модуль мониторинга стабильности тестирует сторонние менеджеры контекста перед тем, как допустить их в контур обработки платежей. Инспектор запускает переданный менеджер и возбуждает внутри его блока контрольное исключение с уникальным маркером. По поведению конструкции модуль отслеживает судьбу ошибки: погасил ли менеджер её в своём методе завершения или позволил всплыть наружу.

Уникальный маркер помогает инспектору не перепутать исходную проверяемую ошибку с новым побочным сбоем, который мог возникнуть уже внутри самого метода завершения при выходе из контекста.

Реализуйте функцию аудита, которая проводит такую проверку и возвращает булев флаг честного подавления контрольной ошибки либо сам исходный объект нового непредвиденного сбоя.

Что уже дано

В редакторе представлена заготовка функции audit_context(manager, control_error) с заглушкой NotImplementedError. Готовые тестовые фабрики и вспомогательные структуры окружения уже доступны при выполнении, реализовывать их заново не требуется.

Что нужно сделать

Реализуйте функцию audit_context(manager, control_error).

Функция принимает два аргумента:

  • manager — синхронный менеджер контекста, метод __enter__ которого завершается успешно и может возвращать произвольный рабочий ресурс;
  • control_error — предоставленный экземпляр исключения (наследник BaseException), снабжённый уникальным маркером.

Функция должна провести ровно один аудит входа и выхода для переданного менеджера и вернуть:

  • True, если менеджер контекста успешно подавил переданное контрольное исключение;
  • False, если то же самое контрольное исключение всплыло наружу;
  • точный исходный объект нового непредвиденного исключения, если метод выхода __exit__ завершился сбоем или выбросил другую ошибку (включая ошибки при вычислении логической истинности результата выхода).

Правила проверки:

  • Запустите стандартный протокол менеджера: в теле контекста должно быть возбуждено именно переданное исключение control_error.
  • Значение, возвращаемое методом __enter__, является ресурсом контекста, а не подменным менеджером.
  • Подавление определяется естественной истинностью результата метода __exit__ (truthiness), включая пользовательские методы приведения к булеву типу, непустые контейнеры и числа. Если при проверке истинности возвращённого значения возникает ошибка, она считается непредвиденным сбоем выхода.
  • Совпадение класса, текста сообщения или перегруженного оператора равенства (__eq__) не делает постороннее исключение контрольным: проверка идентичности опирается на сам исходный объект.
  • Поддерживаются любые подклассы Exception и BaseException.
  • Запрещено клонировать ошибки, возвращать строки вместо объектов или имитировать подавление без фактического выполнения протокола менеджера.

Ввод и вывод

Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня audit_context и вызывает её с проверочными аргументами.

Пример использования

class SuppressingContext:
    def __enter__(self):
        return None
    def __exit__(self, exc_type, exc_value, traceback):
        return True
control = ValueError("control")
control.marker = object()
print(audit_context(SuppressingContext(), control))

Вывод:

True
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи