Попытка понять, как диспетчеры контекста работают для перехвата ошибок, а точнее роль метода __enter__()
в классе, созданном для использования в качестве диспетчера контекста, как он работает здесь в процессе «отлова ошибок» и почему self
это все, что возвращается в методе __enter__()
.
Учитывая следующее использование диспетчера контекста для обнаружения ошибки:
import unittest
class InvoiceCalculatorTests(unittest.TestCase):
def test_no_pay(self):
with self.assertRaises(ValueError):
pay = divide_pay(0, {"Alice": 3.0, "Bob": 3.0, "Carol": 6.0})
Вот то, что я считаю исходным кодом для assertRaises
:
class _AssertRaisesContext(_AssertRaisesBaseContext):
"""A context manager used to implement TestCase.assertRaises* methods."""
_base_type = BaseException
_base_type_str = 'an exception type or tuple of exception types'
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, tb):
if exc_type is None:
try:
exc_name = self.expected.__name__
except AttributeError:
exc_name = str(self.expected)
if self.obj_name:
self._raiseFailure("{} not raised by {}".format(exc_name,
self.obj_name))
else:
self._raiseFailure("{} not raised".format(exc_name))
else:
traceback.clear_frames(tb)
if not issubclass(exc_type, self.expected):
# let unexpected exceptions pass through
return False
# store exception, without traceback, for later retrieval
self.exception = exc_value.with_traceback(None)
if self.expected_regex is None:
return True
expected_regex = self.expected_regex
if not expected_regex.search(str(exc_value)):
self._raiseFailure('"{}" does not match "{}"'.format(
expected_regex.pattern, str(exc_value)))
return True
Я попытался просмотреть PEP-0343, чтобы получить некоторое представление, но это немного за пределами моих текущих знаний/понимания, чтобы понять, что там содержится. Может ли кто-нибудь объяснить, с точки зрения относительного непрофессионала, роль __enter__()
и __exit__()
в процессе «поймать» ValueError здесь и почему __enter__()
просто возвращает себя?