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
