problem with closures

A

alain

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
 
G

Gerard Brunick

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.
('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 inner():
.... print x
.... return inner
....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.


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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top