interface boilerplate

Alex Martelli aleaxit at yahoo.com
Mon Oct 18 16:57:43 CEST 2004


John Hunter <jdhunter at ace.bsd.uchicago.edu> wrote:

> >>>>> "Alex" == Alex Martelli <aleaxit at yahoo.com> writes:
> 
>     Alex> To make a function just like another but with a different
>     Alex> name:
> 
>     Alex> def changed_name_function(f, newname): import new return
>     Alex> new.function(f.func_code, f.func_globals, newname,
>     Alex> f.func_defaults, f.func_closure)
> 
>     Alex> I believe this should work in 2.2 as well (not tested).
> 
> I tested this - the signature of new.function in 2.2 is a bit
> different
> 
> function(...)
>     Create a function object from (CODE, GLOBALS, [NAME [, ARGDEFS]]).
> 
> so it doesn't take the 5 arg version posted.  

Ah, it didn't take a closure.  Could be quite a problem...

> I am having a little trouble figuring out how to handle the call
> signature for 2.2.  I tried this modification (matplotlib._python23 is
> a flag that returns True iff python version >=2.3
> 
> 
> def changed_name_function(f, newname):
>     import new
>     if matplotlib._python23:
>         newf =  new.function(f.func_code, f.func_globals, newname,
>                              f.func_defaults, f.func_closure)
>     else:
>         if f.func_defaults is None:
>             argdefs = ()
>         else:
>             argdefs = f.func_defaults
>         newf =  new.function(f.func_code, f.func_globals, newname,
>                              argdefs)
> 
>     newf.__doc__ = f.__doc__
>     return newf
> 
> I added the None check on f.func_defaults because I was getting the
> error
> 
>   TypeError: function() argument 4 must be tuple, not None
> 
> But this does not appear to be right either because I get a segfault
> :-(  Note that the suggestion works as advertised for python2.3.
> 
> Any ideas?

Supporting old versions is never going to be easy -- I don't even have a
2.2 installation around to do such tests, any more.  Perhaps for
versions < 2.3 you could simply degrade gracefully to perform no
renaming (and for versions >= 2.4 do the renaming the right way, by
assigning to f.func_name and returning f)... those who choose to stick
with 2.2 will just have to account that as one of the many limitations
and slow-downs their choice buys them...


Alex



More information about the Python-list mailing list