user642770
user642770

Reputation: 415

python contextlib closing prevents enter/exit calls

Most likely I don't understand this fully but I have a class declared like

class db:
    def __init__(self, name):
        pass
        #self._conn = get_conn(name)
    
    def __enter__(self):
        print('enter')
        #self_conn.begin_transaction()
    def __exit__(self, a, b, c):
        print('exit')
        #self._conn.commit()
    def close(self):
        print('close')
        #self._conn.close()

When I use it like:

with db('bname') as db:
    print('do something')

I get the expected output like:

enter
do something
exit

but when I use contextlib closing those functions don't get called at all

from contextlib import closing

with closing(db('bname')) as db:
    print('do something')

I only get:

do something
close

My understanding was the contextlib closing can be used with context manager classes to call close always but what am i missing?

Upvotes: 1

Views: 726

Answers (2)

Balaji Ambresh
Balaji Ambresh

Reputation: 5037

The closing class implements its own version of __exit__. This calls close().

Since you're passing an instance of closing to the with block, the __exit__ method of the closing instance will get called and not yours.

Subclass the closing class for your __exit__ to get called. Here's an example:

from contextlib import closing


class Db(closing):
    def __init__(self):
        super().__init__(self)
        print('initializing')

    def close(self):
        print('closing')

    def __enter__(self):
        print('entering')

    def __exit__(self, *exc_info):
        print('exiting')
        return super().__exit__(*exc_info)


with Db() as db:
    print('running')

Output

initializing
entering
running
exiting
closing

Upvotes: 4

Milan Cermak
Milan Cermak

Reputation: 8064

It is the with statement that executes the __enter__ and __exit__ blocks. In your second example, you are applying in on the closing function, not on your db class. That's why those methods don't get triggered.

Upvotes: 1

Related Questions