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
>

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to