Vit Bernatik
Vit Bernatik

Reputation: 3802

IronPython - proper resources deallocation on sys.exit()

What is the best way to properly finalize python script when sys.exit() is called?

For example I have an app which: - opened log file - opened some USB gadget - decide it's time to close the app - call sys.exit(-1) - (or alternatively it throw harsh exception - but I prefer first way as I was little piggy and some parts of code actually catch all exceptions, which would stop my termination exception...)

Then I would need some finalize() function which would be certainly called before exiting the interpreter. Finalize() would free USB gadget and close log file in exactly this order.

I tried def del but it is not called upon sys.exit and furthermore I can not decide in which order _del_s would be called.

Is there some salvation for me? Or do I have to do: 1. Top most try-catch-finally 2. Do the exit with some specific Exception 3. everywhere on each exception catch specify exactly what I'm catching?

Upvotes: 1

Views: 801

Answers (2)

Vit Bernatik
Vit Bernatik

Reputation: 3802

Ok I found the answer which suites me best:

import sys
try:
  print "any code: allocate files, usb gadets etc "
  try:
    sys.exit(-1) # some severe error occure
  except Exception as e:
    print "sys.exit is not catched:"+str(e)
  finally:
    print "but all sub finallies are done"
  print "shall not be executed when sys.exit called before"
finally:
  print "Here we can properly free all resources in our preferable order"
  print "(ie close log file at the end after closing all gadgets)"

as for recommended solution atexit - it would be nice and all but it does not work in my python 2.6. I tried this:

import sys
import atexit

def myFinal():
  print "it doesn't print anything in my python 2.6 :("

atexit.register(myFinal)

print "any code"
sys.exit(-1) # is it pluged in?
print "any code - shall not be execute"

As for Wrapper solution - it's definitely most fancy - but honestly I can not say how it's better...

import sys
class mainCleanupWrapper(object):
    def __enter__(self):
        print "preallocate resources optionally"

    def __exit__(self, type, value, traceback):
        print "I release all resources in my order"

with mainCleanupWrapper() as whatsThisNameFor:
        print "ok my unchaged code with any resources locking"
        sys.exit(-1)
        print "this code shall not be executed" 

I found my solution - but frankly python seems to be getting pretty bulky and bloated...

Upvotes: 0

0xc0de
0xc0de

Reputation: 8307

See python's with statement.

class UsbWrapper(object):
    def __enter__(self):
        #do something like accessing usb_gadget (& acquire lock on it)
        #usb_gadget_handle = open_usb_gadget("/dev/sdc")
        #return usb_gadget_handle

    def __exit__(self, type, value, traceback):
        #exception handling goes here
        #free the USB(lock) here

with UsbWrapper() as usb_device_handle:
        usb_device_handle.write(data_to_write)

No matter whether the code throws exception or runs as desired, the USB lock is always released.

Upvotes: 1

Related Questions