def __exit__(self, exc_type=None, exc_value=None, traceback=None):
assert self._state in ('<STR_LIT>', '<STR_LIT>'), '<STR_LIT>'<EOL>self._state = '<STR_LIT>'<EOL>if exc_type is not None and exc_value is None:<EOL><INDENT>exc_value = exc_type()<EOL><DEDENT>generators, self._middleware_generators = self._middleware_generators, None<EOL>while generators:<EOL><INDENT>__, generator = generators.pop()<EOL>try:<EOL><INDENT>if self._exit(generator, exc_type, exc_value, traceback):<EOL><INDENT>exc_type, exc_value, traceback = (None, None, None)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>exc_type, exc_value, traceback = sys.exc_info()<EOL>exc_value = exc_value or exc_type()<EOL><DEDENT><DEDENT>try:<EOL><INDENT>self._teardown_hook(exc_value)<EOL><DEDENT>except:<EOL><INDENT>self._resource_exit_errors.append(sys.exc_info())<EOL><DEDENT>finally:<EOL><INDENT>resources, self._resource_generators = self._resource_generators, None<EOL>while resources:<EOL><INDENT>__, resource_generator = resources.popitem()<EOL>try:<EOL><INDENT>self._exit(resource_generator, exc_type, exc_value, traceback)<EOL><DEDENT>except:<EOL><INDENT>self._resource_exit_errors.append(sys.exc_info())<EOL><DEDENT><DEDENT>try:<EOL><INDENT>if exc_type:<EOL><INDENT>raise exc_type(exc_value).with_traceback(traceback)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>try:<EOL><INDENT>self._final_hook(exc_value)<EOL><DEDENT>finally:<EOL><INDENT>self.data_manager.ctx_stack.pop()<EOL>self._state = '<STR_LIT>'<EOL><DEDENT><DEDENT><DEDENT>
Close all open resources, middleware and
remove context from stack

In-context exceptions (exceptions raised between ``__enter__``
and ``__exit__``) are propagated to Middleware, Resources, and
eventually raised outside the ``DataAccessContext``. Resources
are created in-context so if a Resource raises an exception
during setup, it treated the same as all in-context exceptions.

Middleware may suppress or replace the in-context exception. If
there is an unhandled exception raised in-context or by middleware
it is guaranteed to be raised outside the ``DataAccessContext``.

If a Resource raises an exception, it is collected and all
other Resource will still close. Resource exit exceptions do not
propagate. The Resource will only see the in-context/middleware
exception. To access Resource exit exceptions, use
``DataAccessContext.get_resource_exit_errors()``.