AdjunctProfessorFalcon
AdjunctProfessorFalcon

Reputation: 1840

Understanding purpose of returning self in context manager class

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

Answers (1)

Chad S.
Chad S.

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

Related Questions