atexit missing an unregister method

I was looking at the atexit module the other day; it seems like an elegant way to ensure that resources are cleaned up (that the garbage collector doesn't take care of). But while you can mark functions to be called with the 'register' method, there's no 'unregister' method to remove them from the stack of functions to be called. Nor is there any way to view this stack and e.g. call 'del' on a registered function. This would be useful in the following scenario, in which x and y are resources that need to be cleaned up, even in the event of a program exit: import atexit def free_resource(resource): ... atexit.register(free_resource, x) atexit.register(free_resource, y) # do operations with x and y, potentially causing the program to exit ... # if nothing caused the program to unexpectedly quit, close the resources free_resource(x) free_resource(y) #unregister the functions, so that you don't try to free the resources twice! atexit.unregisterall() Alternatively, it would be great if there were a way to view the stack of registered functions, and delete them from there. --Nick Jacobson _________________________________________________________________ Dont just search. Find. Check out the new MSN Search! http://search.msn.click-url.com/go/onm00200636ave/direct/01/

[Nick Jacobson]
I was looking at the atexit module the other day; it seems like an elegant way to ensure that resources are cleaned up (that the garbage
collector > doesn't take care of). > > But while you can mark functions to be called with the 'register' method, > there's no 'unregister' method to remove them from the stack of functions > to > be called. . . . > Alternatively, it would be great if there were a way to view the stack of > registered functions, and delete them from there.
Please file a feature request on SourceForge. Will mull it over for a while. My first impression is that try/finally is a better tool for the scenario you outlined. The issue with unregister() is that the order of clean-up calls is potentially significant. If the same function is listed more than once, there would be no clear-cut way to know which should be removed when unregister() is called. Likewise, I suspect that exposing the stack will create more pitfalls and risks than it could provide in benefits. Dealing with a stack of functions is likely to be clumsy at best. Raymond Hettinger

On 4/26/05, Nick Jacobson <nicksjacobson@hotmail.com> wrote:
I was looking at the atexit module the other day; it seems like an elegant way to ensure that resources are cleaned up (that the garbage collector doesn't take care of).
But while you can mark functions to be called with the 'register' method, there's no 'unregister' method to remove them from the stack of functions to be called. Nor is there any way to view this stack and e.g. call 'del' on a registered function.
This would be useful in the following scenario, in which x and y are resources that need to be cleaned up, even in the event of a program exit:
import atexit
def free_resource(resource): ...
atexit.register(free_resource, x) atexit.register(free_resource, y) # do operations with x and y, potentially causing the program to exit ... # if nothing caused the program to unexpectedly quit, close the resources free_resource(x) free_resource(y) #unregister the functions, so that you don't try to free the resources twice! atexit.unregisterall()
Alternatively, it would be great if there were a way to view the stack of registered functions, and delete them from there.
Methinks that the resource cleanup routines ought to be written so as to be reentrant. That shouldn't be too hard (you can always maintain a global flag that means "already called"). -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Nick> But while you can mark functions to be called with the 'register' Nick> method, there's no 'unregister' method to remove them from the Nick> stack of functions to be called. Nor is there any way to view Nick> this stack and e.g. call 'del' on a registered function. Nick> This would be useful in the following scenario, in which x and y Nick> are resources that need to be cleaned up, even in the event of a Nick> program exit: Nick> import atexit Nick> def free_resource(resource): Nick> ... Nick> atexit.register(free_resource, x) Nick> atexit.register(free_resource, y) Nick> # do operations with x and y, potentially causing the program to exit Nick> ... Nick> # if nothing caused the program to unexpectedly quit, close the resources Nick> free_resource(x) Nick> free_resource(y) Nick> #unregister the functions, so that you don't try to free the resources Nick> twice! Nick> atexit.unregisterall() This seems like a poor argument for unregistering exit handlers. If you've registered an exit handler, why then explicitly do what you've already asked the system to do? Also, your proposed unregisterall() function would be dangerous. As an application writer you don't know what other parts of the system (libraries you use, for example) might have registered exit functions. Skip

On Tue, Apr 26, 2005, Nick Jacobson wrote:
I was looking at the atexit module the other day; it seems like an elegant way to ensure that resources are cleaned up (that the garbage collector doesn't take care of).
But while you can mark functions to be called with the 'register' method, there's no 'unregister' method to remove them from the stack of functions to be called. Nor is there any way to view this stack and e.g. call 'del' on a registered function.
This would be useful in the following scenario, in which x and y are resources that need to be cleaned up, even in the event of a program exit:
import atexit
def free_resource(resource): ...
atexit.register(free_resource, x) atexit.register(free_resource, y)
This seems like the wrong way. Why not do this: class ResourceCleanup: def register(self, resource, func): ... def unregister(self, resource): ... def __call__(self): ... handler = ResourceCleanup) atexit.register(handler) handler.register(x, free_resource) do(x) handler.unregister(x) Probably further discussion should go to comp.lang.python -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "It's 106 miles to Chicago. We have a full tank of gas, a half-pack of cigarettes, it's dark, and we're wearing sunglasses." "Hit it."

Nick Jacobson wrote:
But while you can mark functions to be called with the 'register' method, there's no 'unregister' method to remove them from the stack of functions to be called.
You can always build your own mechanism for managing cleanup functions however you want, and register a single atexit() hander to invoke it. I don't think there's any need to mess with the way atexit() currently works. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg.ewing@canterbury.ac.nz +--------------------------------------+
participants (6)
-
Aahz
-
Greg Ewing
-
Guido van Rossum
-
Nick Jacobson
-
Raymond Hettinger
-
Skip Montanaro