Reputation: 1840
Trying to understanding how context managers work to catch errors, but more specifically the role of the __enter__()
method in a class created to be used as a context manager, how it works in the 'error catching' process here, and why it is that self
is all that's returned in the __enter__()
method.
Given the following use of a context manager to catch an error:
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})
Here is what I believe is the source code for 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
I've tried going through PEP-0343 to gain some insight, but it's a bit beyond my current knowledge/understanding to make sense of what's contained therein. Could someone explain, in relative layman's terms, the role of __enter__()
and __exit__()
in the process of 'catching' the ValueError here and why it is that __enter__()
is just returning self?
Upvotes: 3
Views: 1784
Reputation: 6631
__enter__()
is for setup, This particular context manager doesn't require any setup. So all it has to do is return object to be specified in the as
clause, which is just itself.
Upvotes: 2