2

Imagine we have a context manager called abc. So in the below code does the __exit__method defined inside abc be called if there's an exception.

with abc:
    print("entered context manager")
    raise Exception("raising exception")


Murali K
  • 186
  • 2
  • 13

2 Answers2

1

Yes, according to the docs. The __exit__ method receives the exception as arguments:

object.__exit__(self, exc_type, exc_value, traceback)

Exit the runtime context related to this object. The parameters describe the exception that caused the context to be exited. If the context was exited without an exception, all three arguments will be None.

This question has a lot more answers and information.

It was the first google result when I typed in python __exit__ exception.

Community
  • 1
  • 1
Ralf
  • 16,086
  • 4
  • 44
  • 68
  • My context manager is from library which I have installed, I tried adding print statements inside source code to check if `__exit__` is being called and I didn't see any of them getting executed in terminal... well it didn't appear for `__enter__ `as well. Am I missing something? why are my print statements inside source code isn't getting executed? – Murali K May 29 '20 at 13:21
0

Let's say this is your custom context manager:

class CustomTransaction(object):

    def __init__(self, id):
        self.id = id
        print('init')

    def __enter__(self):
        if self.id:
            print('User_{} acquired transaction lock'.format(self.id))
        else:
            print('Raising an exception from __enter__ method')
            raise Exception('id was not specified')

        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is None:
            print('User_{} released transaction lock'.format(self.id))
        else:
            print('User_{} failed to complete transaction block'.format(self.id))

Here is how it's going to behave depending on if and where an exception occurs:

1. Transaction block won't be completed

with CustomTransaction(id=1) as t:
    print('Doing some work...')
    print('Raising an exception...')
    raise Exception('Error. Something went wrong!')
    print('Won\'t be printed...')

output:

init
User_1 acquired transaction lock
Doing some work...
Raising an exception...
User_1 failed to complete transaction block

2. Transaction block will be successfully completed

with CustomTransaction(id=2) as t:
    print('Doing some work...')
    print('Doing even more heavy work...')

output:

init
User_2 acquired transaction lock
Doing some work...
Doing even more heavy work...
User_2 released transaction lock

3. Transaction block won't even start excecuting because the enter method raises an exception

with CustomTransaction(None) as t:
    print('Won\'t be printed')

output:

init
Raising an exception from the __enter__ method
Taras Mykhalchuk
  • 829
  • 1
  • 9
  • 20