Hello Holger, Ok, I am working on refactoring things to our "almost-common" view :-) On Tue, Aug 05, 2003 at 11:08:13AM +0200, holger krekel wrote:
(...) really only if you pass arguments. There are code objects that are simply executed in a context of scopes - no argument parsing stuff whatsoever.
Yes, you are right here. I am now putting argument parsing code in a new Function class, where it seems to belong. Statements like 'exec code' should not create a function object at all, nor involve argument parsing. We have a potential difference with CPython here, however, because argument parsing is always done in CPython: e.g.
def f(x): pass ... exec f.func_code Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: f() takes exactly 1 argument (0 given)
In the model corresponding to the refactoring, the 'exec' statement would work slightly differently. All frame objects now have getxxx() and setxxx() accessors to read or write data in various ways, including setlocaldict(d) and setlocalvar(index, value). The former sets the locals dictionary (and calls locals2fast if needed, to keep the fast variables in sync), which the latter directly sets the indexth local variable. The argument parsing stuff in Function calls setlocalvar() to initialize the frame, while the 'exec' statement calls setlocaldict(). It means that the following would work in PyPy but not in CPython :
def f(x): pass ... exec f.func_code in {'x': 5}
I cannot see a real problem in allowing this to work in PyPy, as it is somehow a more regular behavior; in CPython it explicitely doesn't work because of the fast locals optimization. Note that by extension I expect the following behavior in PyPy:
def f(x): ... print x ... exec f.func_code in {} Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in f UnboundLocalError: local variable 'x' referenced before assignment
Note that the error only shows up on the 'print x' statement. Anyone has a reason to forbid this ? The 'exec' statement seems quite low-level anyway, and I don't expect it to be normally used for code objects from 'func_code' attributes. Armin