enhancements scope transformimpl
This is to answer the question: How to solve the scoping problem using a simple transform? (This might not be the proper solution, just investigating. I know too little about why the current variable scoping is broken.)
(Btw there's some rationale for doing this: It would closely emulate how the Python parser works when interpreting the module scope -- almost simulate running the module-level code (though with an eye only for the namespace handling). This kind of stuff (emulating the simple Python parser) is imnsho much easier to do with a visitor than in a recursive process.)
What one does: Transform every variable assignment, and reference, but the last one, to a temporary. I.e:
#!python
import math
f = 3
f = 34 + math.sin(f)
class f:
x = f
x = 2*f
x = f()
def f(y):
return x(y)
def x(z):
return 4
By a single pass (keeping track of names assigned to in AssignmentNodes and references to them in NameNode in dicts and lists) one can without much pain (= ~50 lines of "interesting but not really challenging code") transform this to (where each tmpx variable is a TempNode that doesn't name-clash with variables named tmpx, of course. Also the tmpx variables does not enter the module dict):
#!python
tmp1 = 3
tmp2 = 34 + math.sin(tmp1)
class tmp3:
tmp4 = tmp2
x = tmp4
tmp5 = tmp3()
def f(y):
return x(y) # Python semantics is to keep x here now, and not tmp4 which is x at definition time? Transform can work either way.
def tmp6(z):
return 4
This will in turn cause static linking in the correct way everywhere.
In addition, some fudging of the function names stored etc. is needed (add an "should_appear_as" attribute to TempNode and use it in code generation of a function), but that appears to be it?
The same transform could easily raise an error when a global name is used before it is defined too.