Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have contextlib.closing() to call an arbitrary cleanup method instead of .close()

I was running into some problems using with statement(PEP 343) in python to automatically manage resource clean up after the context. In particular, with statement always assumes the resource clean up method is .close(). I.E. in the following block of code, browser.close() is automatically getting called when execution runs out of the context, however, browser.close() is not the proper clean up as it only close the current window not the entire browser. What it should have done is to call browser.quit().

with contextlib.closing(webdriver.Firefox()) as browser:
    # do something with browser
# at this point browser.close() has been called.

Unfortunately, contextlib.closing doesn't provide a way to customize the clean-up method name to be called, as evidently seen here:

 def __exit__(self, *exc_info):
      self.thing.close()

However, I do notice that there is an argument exec_info but was not used in that particular method. Anybody knows why?

The bigger question is, as title suggested, if possible, how to have self.thing to call an arbitrary clean up method? If not, what's the best work around? Should I fall back to use try...finally?

like image 333
Devy Avatar asked Sep 13 '13 19:09

Devy


1 Answers

Well, it's python, you can make your own closing class, based on contextlib.closing and override __exit__() method:

import contextlib
from selenium import webdriver

class closing(contextlib.closing):
    def __exit__(self, *exc_info):
        self.thing.quit()


with closing(webdriver.Firefox()) as browser:
    browser.get('http://stackoverflow.com')

FYI, there was a proposal to make webdriver a context manager, but it was closed as won't fix since quit() is the right way to close the browser, and it should be called explicitly, see Make webdriver a context manager [python bindings].

like image 155
alecxe Avatar answered Oct 05 '22 03:10

alecxe