From: arcege at shore.net (Michael P. Reilly)
Date: Fri, 23 Apr 1999 21:35:05 GMT
Subject: Proposed Change for sys.exitfunc for version 1.6
References: <37209360.2FB8E145@collins.rockwell.com>
Message-ID: <dI5U2.232$7j4.78941@news.shore.net>
Content-Length: 2193
X-UID: 1556                                                  

Jonathan Polley <jwpolley at collins.rockwell.com> wrote:
: I would like to propose adding a function to the module 'sys' that would
: change (slightly) the behavior of sys.exitfunc.  I would like to add a
: method that performs the same function as UNIX's 'atexit ()' function.
: The reason is that I have some modules that would like to do some
: cleanup when python terminates, but I don't want to have to add the code
: required for them to remember the previous value of sys.exitfunc so they
: can call that function (if present).  A method sys.atexit () would work
: nicely.  It would allow me to add a series of exit functions and be
: guaranteed that they would all be called at the termination of python
: (so I can close files, purge queues, close sockets, etc.).  Does anyone
: else think this would be a good idea???

Files and sockets will be closed (and flushed), and if you have a queue
it is problem an instance of a class and an appropriate __del__ method
can be created.

  import os
  class LockFile:
    os_remove = os.remove  # do not rely on os still existing
    def __del__(self):
      if self.locked:
        self.os_remove(self.file)

Then if the os module is destroyed during exit clean-up, my class (and
the instances) still have access to the functions it needs.

There is little need in the object-oriented world to have atexit
functionality.  There used to be some race-condition problems with this
as well (I explained one of them above).  However, the C API does have
the function Py_AtExit() which does this (C modules aren't quite the
same as Python modules ;).

But if you want to make a atexit callback subsystem:

  class SysAtExit:
    def __init__(self):
      self.callbacks = []
    # the instance is callable itself
    def __call__(self, func):
      if callable(func):
        self.callbacks.append(func)
      else:
        raise TypeError, "not a callable"
    def on_exit(self):
      for func in self.callbacks:
        func()
  import sys
  sys.atexit = SysAtExit()
  sys.exitfunc = sys.atexit.on_exit
  del SysAtExit, sys

Then in your own code, call:
  sys.atexit(my_func_to_call_at_exit)

There is (almost) always a way. ;)

  -Arcege





