472,119 Members | 1,584 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,119 software developers and data experts.

problem with closures

Hi,

I have a problem with closures.
I am trying to implement yet another design by contract decorator which
would look like the following:
<pre>
def contract(f):
def newf(*args, **kw):
import new
precondition = new.function(f.func_code.co_consts[1],
f.func_globals,'pre',
f.func_defaults,
f.func_closure)
precondition()
result=f(*args, **kw)
postcondition=new.function(f.func_code.co_consts[2],globals())
postcondition(result)
return result
return newf
@contract
def foo(x,y,g=2,z=1):
def pre():
assert x>1 and 0<y<100
def post(result):
assert result >0
print 'main'
return x+y+z*g

print foo(2,5,4,69)
<pre>

The problem is that i get the following error message on line 7:
TypeError: arg 5 (closure) must be tuple

f.func_closure is indeed empty while
f.func_code.co_consts[1].co_freevars is logically equal to ('x','y').

Thanks for responding

Alain

Dec 6 '06 #1
1 1733
I can't solve your problem, but I can at least explain why I think its
hard. foo doesn't have any closed over
variables. Some of its locals have to live in cells, so that pre and
post can see them in their closures.
>>foo.func_code.co_cellvars
('x', 'y')

Now the only way that I know of to get a local variable to be put in a
cell, where you can then plug
it into a func_closure, it to write a function which a contains a
function with a closure. Moreover, this
requires that the function signatures really match to work. Consider
>>def test(*arg, **args):
.... def inner():
.... print x
.... return inner
....
>>f = test(x=5)
f()
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 3, in inner
NameError: global name 'x' is not defined

Since x isn't a named argument of test, the compiler just assumes that
its a global.
This means that your contract function is going to have to build a
string and exec
to make the newf so its arguments match foo exactly. Of course the
compiler is
really finicky about exec, when there are free variables around, and I
don't claim
to understand the rules.

alain wrote:
Hi,

I have a problem with closures.
I am trying to implement yet another design by contract decorator which
would look like the following:
<pre>
def contract(f):
def newf(*args, **kw):
import new
precondition = new.function(f.func_code.co_consts[1],
f.func_globals,'pre',
f.func_defaults,
f.func_closure)
precondition()
result=f(*args, **kw)
postcondition=new.function(f.func_code.co_consts[2],globals())
postcondition(result)
return result
return newf
@contract
def foo(x,y,g=2,z=1):
def pre():
assert x>1 and 0<y<100
def post(result):
assert result >0
print 'main'
return x+y+z*g

print foo(2,5,4,69)
<pre>

The problem is that i get the following error message on line 7:
TypeError: arg 5 (closure) must be tuple

f.func_closure is indeed empty while
f.func_code.co_consts[1].co_freevars is logically equal to ('x','y').

Thanks for responding

Alain
Dec 7 '06 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by paolo veronelli | last post: by
3 posts views Thread by Fabio Cavassini | last post: by
40 posts views Thread by MartinRinehart | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.