On 20 May 2010 14:39, Haoyu Bai <[email protected]> wrote:
> On Fri, May 21, 2010 at 1:26 AM, Lisandro Dalcin <[email protected]> wrote:
>> On 20 May 2010 13:54, Haoyu Bai <[email protected]> wrote:
>>> Hi,
>>>
>>> While I get the the nonlocal keyword implemented, now the inner
>>> function is able to write to the closure. This cause refnanny lost
>>> tracking on the closure variables when following the refcounting rules
>>> described at http://wiki.cython.org/refcounting . For example:
>>>
>>> def foo():
>>>    x=0 # INCREF(0), 0 get traced by refnanny
>>>    def bar():
>>>        # DECREF(x)  refnanny complains since x is not got tracked yet
>>>        # INCREF(1)
>>>        x=1
>>>        # refnanny complains since there is no giveref for 1
>>>    bar()
>>>    # refnanny complains since 0 is not giveref-ed and 1 got giveref-ed 
>>> instead
>>>
>>>
>>> For the inner function bar() it is easy to fix. But for the outer
>>> function, since the thing x referenced to can be changed at every
>>> point now, it will not work correctly to giveref at the end of
>>> function.
>>>
>>> Since the rule is that closure variables are owned by scope object and
>>> not managed by refnanny. So my idea to fix this is to wrap every
>>> assignment to closure object by a pair of GOTREF and GIVEREF. So when
>>> you do x=1, these will happen:
>>>
>>> GOTREF(x)
>>> DECREF(x)
>>> INCREF(1)
>>> x=1
>>> GIVEREF(x)
>>>
>>> Then refnanny will be happy.
>>>
>>
>> Looks good ...
>>
>>> I implemented this, and got all the closure related tests passed
>>> without refnanny complaining.
>>>
>>> This generate a bit more codes but I think should be ok. Since
>>> refnanny is for debug so performance at here would not be a concern.
>>>
>>
>> Of course, never mind about these extra lines...
>>
>>
>>
>> --
>> Lisandro Dalcin
>
> Thanks! :)
>
> BTW, just spotted a closure bug, this won't compile (reports
> '__pyx_outer_scope' redeclared):
>
> def nested1():
>    def f():
>        def g1():
>            pass
>
> def nested2():
>    def f():
>        def g2():
>            pass
>
> Seems some name mangling problem. I traced to
> CreateClosureClasses.create_class_from_scope() in
> ParseTreeTransform.py then didn't get the idea yet.
>

Does this occur if you write def f2(): ... (instead of def f():...)
in nested2() ? Could the bug be related to f()'s having the same name?



-- 
Lisandro Dalcin
---------------
CIMEC (INTEC/CONICET-UNL)
Predio CONICET-Santa Fe
Colectora RN 168 Km 472, Paraje El Pozo
Tel: +54-342-4511594 (ext 1011)
Tel/Fax: +54-342-4511169
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to