Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Preserving the argspec of a function after generating a closure

Reply
Thread Tools

Preserving the argspec of a function after generating a closure

 
 
Victor Ng
Guest
Posts: n/a
 
      03-11-2005
Is there a way to preserve the argspec of a function after wrapping it
in a closure?

I'm looking for a general way to say "wrap function F in a closure",
such that inspect.getargspec on the closure would return the same
(args, varargs, varkw, defaults) tuple ass the enclosed function.

The typical code I'm using is something like this:

def wrapFunc(func):
def tmpWrapper(*args, **kwargs):
return func(*args, **kwargs)
tmpWrapper.func_name = func.func_name
return wrapFunc

This preserves the function name - how do I do more?

vic

--
"Never attribute to malice that which can be adequately explained by
stupidity." - Hanlon's Razor
 
Reply With Quote
 
 
 
 
Bengt Richter
Guest
Posts: n/a
 
      03-11-2005
On Fri, 11 Mar 2005 11:55:51 -0500, Victor Ng <(E-Mail Removed)> wrote:

>Is there a way to preserve the argspec of a function after wrapping it
>in a closure?
>
>I'm looking for a general way to say "wrap function F in a closure",
>such that inspect.getargspec on the closure would return the same
>(args, varargs, varkw, defaults) tuple ass the enclosed function.
>
>The typical code I'm using is something like this:
>
>def wrapFunc(func):
> def tmpWrapper(*args, **kwargs):
> return func(*args, **kwargs)
> tmpWrapper.func_name = func.func_name
> return wrapFunc
>
>This preserves the function name - how do I do more?

Probably you could use the inspect.getargspec(func) info to
build a wrapper with the identical signature that would call func
passing everything through 1:1, but that would seem kind of useless, unless
you want to substitute some closure values into the func call and get
a currying effect. In that case, your new signature should probably be changed
to reflect the real effective signature of the curried function.

I recently posted a byte-code-munging decorator hack that accomplishes some of that. E.g.,
(I keep presets.py in my ut package, where I accumulate miscellaneous experimental untility stuff)

>>> from ut.presets import presets, curry
>>> @curry(y=123)

... def foo(x, y): return x*y
...
>>> import inspect
>>> inspect.getargspec(foo)

(['x'], None, None, None)
>>> import dis
>>> dis.dis(foo)

1 0 LOAD_CONST 1 (123)
3 STORE_FAST 1 (y)

3 6 LOAD_FAST 0 (x)
9 LOAD_FAST 1 (y)
12 BINARY_MULTIPLY
13 RETURN_VALUE

And without the currying decorator:

>>> def foo(x, y): return x*y

...
>>> inspect.getargspec(foo)

(['x', 'y'], None, None, None)
>>> dis.dis(foo)

1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 BINARY_MULTIPLY
7 RETURN_VALUE


Basically, the curry decorator here injects a local assignment and adjusts the line map
and signature and a few other tweaks, depending.

This doesn't wrap the function though, it modifies it.
I haven't tried decorating indirectly... Hm...
Faking decoration of foo with getf to substitute the func passed ...

>>> def wrap(func, y):

... def getf(f): return func
... @curry(y=y)
... @getf
... def foo(): pass
... foo.func_name = func.func_name
... return foo
...
>>> def bar(x, y): return x+y

...
>>> wbar = wrap(bar, 1000)
>>> wbar

<function bar at 0x02F1AAE4>
>>> bar(123)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: bar() takes exactly 2 arguments (1 given)

oops, that should have been wbar ...

>>> wbar(123)

1123
>>> inspect.getargspec(wbar)

(['x'], None, None, None)
>>> import dis
>>> dis.dis(wbar)

1 0 LOAD_CONST 1 (1000)
3 STORE_FAST 1 (y)

3 6 LOAD_FAST 0 (x)
9 LOAD_FAST 1 (y)
12 BINARY_ADD
13 RETURN_VALUE

>>> inspect.getargspec(bar)

(['x', 'y'], None, None, None)
>>> dis.dis(bar)

1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 BINARY_ADD
7 RETURN_VALUE

I don't know where this is leading. What was your goal again?

Regards,
Bengt Richter
 
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
Sign preserving Vs value preserving sophia.agnes@gmail.com C Programming 4 12-07-2007 03:14 PM
integral promotion, arithmetic conversion, value preserving, unsigned preserving??? TTroy C Programming 16 01-31-2005 10:20 PM
Preserving the original URL in address bar after a redirect. Lee Farrant ASP General 2 12-24-2003 12:18 PM
preserving vars sent by POST method after redirecting by .htaccess joe Perl Misc 0 08-04-2003 09:55 PM
Perl hangs when returning lvalue closure from another lvalue closure Julian Mehnle Perl Misc 0 07-17-2003 03:13 PM



Advertisments