Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > atexit.register does not return the registered function. IMHO, it should.

Reply
Thread Tools

atexit.register does not return the registered function. IMHO, it should.

 
 
prouleau001@gmail.com
Guest
Posts: n/a
 
      11-16-2006
Hi all!

Since that the decorator syntax is upon us, I think it would be good if
atexit.register() was returning the function passed as argument. This
simple change to the library would solve a problem with the use of
atexit.register as a decorator (and I can't think of any use case where
this change would break any code).

I describe the problem in the following text.

Problem using atexit.register as a decorator
============================================

In his April 2005 article titled `Python 2.4 Decorators: Reducing code
duplication and consolidating knowledge`_ , Phillip Eby describes how
you can use `atexit.register()`_ from the standard Python library. He
shows how to use the decorator syntax to register a function that will
execute at program termination. Here is how it goes::

@atexit.register
def goodbye():
print "Goodbye, terminating..."


However, there is one fundamental problem with this: atexit.register()
returns None. Since the above code corresponds to::


def goodbye():
print "Goodbye, terminating..."
goodbye = atexit.register(goodbye)

the code registers goodbye but right after it binds goodbye to None!
You can see this in the following session::

>>> import atexit
>>> @atexit.register

... def goodbye():
... print "Goodbye, terminating..."
...
>>> goodbye()

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'NoneType' object is not callable
>>>
>>> goodbye
>>> type(goodbye)

<type 'NoneType'>
>>>


There is two solutions to this problem:

1. Use another function to register and decorate.
2. Change atexit.register() in the Python library so that
it returns the function it registers.

Solution 1 can be implemented right away::

def atexit_register(fct):
atexit.register(fct)
return fct

@atexit_register
def goodbye2():
print "Goodbye 2!!"

and it works: it registers the function for execution at termination
but leaves goodbye2 callable::

>>> def atexit_register(fct):

... atexit.register(fct)
... return fct
...
>>> @atexit_register

... def goodbye2():
... print "Goodbye 2!!"
...
>>> goodbye2()

Goodbye 2!!
>>> goodbye2

<function goodbye2 at 0x009DD930>
>>>


... References

... _atexit.register():
http://www.python.org/doc/current/li...le-atexit.html
... _Python 2.4 Decorators\: Reducing code duplication and consolidating
knowledge: http://www.ddj.com/184406073

 
Reply With Quote
 
 
 
 
Skip Montanaro
Guest
Posts: n/a
 
      11-16-2006
> Since that the decorator syntax is upon us, I think it would be good if
> atexit.register() was returning the function passed as argument. This
> simple change to the library would solve a problem with the use of
> atexit.register as a decorator (and I can't think of any use case where
> this change would break any code).

....

Can you submit a bug report to the SourceForge bug tracker? I'll take
care of the problem when I have access to the subversion repository.

Skip
 
Reply With Quote
 
 
 
 
Pierre Rouleau
Guest
Posts: n/a
 
      11-16-2006
On 11/16/06, Skip Montanaro <(E-Mail Removed)> wrote:
> > Since that the decorator syntax is upon us, I think it would be good if
> > atexit.register() was returning the function passed as argument. This
> > simple change to the library would solve a problem with the use of
> > atexit.register as a decorator (and I can't think of any use case where
> > this change would break any code).

> ...
>
> Can you submit a bug report to the SourceForge bug tracker? I'll take
> care of the problem when I have access to the subversion repository.
>

Done: http://sourceforge.net/tracker/index...70&atid=105470

I select Python 2.5 as the category. It affects all versions but most
likely to cause a problem in Python 2.4 and after.

--

Pierre R.
 
Reply With Quote
 
Carsten Haese
Guest
Posts: n/a
 
      11-16-2006
On Thu, 2006-11-16 at 08:03 -0800, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> @atexit.register
> def goodbye():
> print "Goodbye, terminating..."
>
>
> However, there is one fundamental problem with this: atexit.register()
> returns None. Since the above code corresponds to::
>
>
> def goodbye():
> print "Goodbye, terminating..."
> goodbye = atexit.register(goodbye)
>
> the code registers goodbye but right after it binds goodbye to None!


While it wouldn't hurt to have atexit.register return the function it
registered, this "problem" is only a problem if you wish to call the
function manually, since atexit already registered the reference to the
intended function before your reference to it gets rebound to None.
Normally one would register a function with atexit precisely because
they don't want to call it manually.

-Carsten


 
Reply With Quote
 
prouleau001@gmail.com
Guest
Posts: n/a
 
      11-16-2006


On Nov 16, 11:38 am, Carsten Haese <(E-Mail Removed)> wrote:
> On Thu, 2006-11-16 at 08:03 -0800, (E-Mail Removed) wrote:
> > @atexit.register
> > def goodbye():
> > print "Goodbye, terminating..."

>
> > However, there is one fundamental problem with this: atexit.register()
> > returns None. Since the above code corresponds to::

>
> > def goodbye():
> > print "Goodbye, terminating..."
> > goodbye = atexit.register(goodbye)

>
> > the code registers goodbye but right after it binds goodbye to None!While it wouldn't hurt to have atexit.register return the function it

> registered, this "problem" is only a problem if you wish to call the
> function manually, since atexit already registered the reference to the
> intended function before your reference to it gets rebound to None.
> Normally one would register a function with atexit precisely because
> they don't want to call it manually.
>

There are *two* problems.

1 - As you said, most of the time you would not call the function
explicitly, but in some situation you might want to.
2- If you want to document your code using introspection, or use an
IDE to look at the function, if the function disappeared from sight,
you won't be able to.


The second problem is similar to what happens when a decorator changes
the signature of a function.

--

P.R.

 
Reply With Quote
 
Georg Brandl
Guest
Posts: n/a
 
      11-16-2006
Skip Montanaro schrieb:
>> Since that the decorator syntax is upon us, I think it would be good if
>> atexit.register() was returning the function passed as argument. This
>> simple change to the library would solve a problem with the use of
>> atexit.register as a decorator (and I can't think of any use case where
>> this change would break any code).

> ...
>
> Can you submit a bug report to the SourceForge bug tracker? I'll take
> care of the problem when I have access to the subversion repository.


Sorry, didn't read this thread before the bug report, which is why I
already handled this one

cheers,
Georg
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
COM object with CLSID is either not valid or registered issue with ASP.NET not Windows. Jen ASP .Net 2 02-18-2010 01:37 AM
COM object with CLSID is either not valid or not registered =?Utf-8?B?Sm9lbA==?= ASP .Net 3 03-22-2005 11:37 AM
what value does lack of return or empty "return;" return Greenhorn C Programming 15 03-06-2005 08:19 PM
COM object with CLSID {10020200-EB1C-11CF-AE6E-00AA004A34D5} is either not valid or not registered Baski ASP .Net 2 12-21-2004 11:37 PM
COM object with CLSID {00024500-0000-0000-C000-000000000046} is either not valid or not registered. =?Utf-8?B?SlJPQ2FtYXJv?= ASP .Net 6 04-07-2004 01:48 PM



Advertisments