problem with closures

Discussion in 'Python' started by alain, Dec 6, 2006.

  1. alain

    alain Guest

    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
    alain, Dec 6, 2006
    #1
    1. Advertising

  2. 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
    >
    Gerard Brunick, Dec 7, 2006
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kasper B. Graversen

    Closures in python

    Kasper B. Graversen, Sep 18, 2003, in forum: Python
    Replies:
    11
    Views:
    681
    David Eppstein
    Sep 21, 2003
  2. Tom Plunket

    Problem understanding how closures work

    Tom Plunket, Dec 12, 2006, in forum: Python
    Replies:
    3
    Views:
    283
    Tom Plunket
    Dec 12, 2006
  3. Louis Steinberg

    problem with lambda / closures

    Louis Steinberg, Nov 30, 2009, in forum: Python
    Replies:
    1
    Views:
    244
    Marco Mariani
    Nov 30, 2009
  4. Terry Reedy

    Re: problem with lambda / closures

    Terry Reedy, Nov 30, 2009, in forum: Python
    Replies:
    2
    Views:
    276
    Terry Reedy
    Dec 1, 2009
  5. Replies:
    2
    Views:
    70
Loading...

Share This Page