Very recent test_global failure
Windows.
python ../lib/test/regrtest.py test_global test_global <test code>:2: SyntaxWarning: name 'a' is assigned to before global declaration <test code>:2: SyntaxWarning: name 'b' is assigned to before global declaration The actual stdout doesn't match the expected stdout. This much did match (between asterisk lines):
test_global ********************************************************************** Then ... We expected (repr): 'got SyntaxWarning as e' But instead we got: 'expected SyntaxWarning' test test_global failed -- Writing: 'expected SyntaxWarning', expected: 'got SyntaxWarning as e' 1 test failed: test_global
Just fixed. Guido's new, handy-dandy warning helper for the compiler checks for a warning that has been turned into an error. If the warning becomes an error, the SyntaxWarning is replaced with a SyntaxError. The change broke this test, but was otherwise a good thing. It allows reasonable tracebacks to be produced. Jeremy
Oops. Missed a checkin to symtable.h. unix-users-prepare-to-recompile-everything-ly y'rs, Jeremy
Hi. Is the following true? PEP227 states: """ If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. """ but this is a bit ambiguous, because the global decl (I imagine for backw-compatibility) does not affect the code blocks of nested (func) definitions. So x=7 def f(): global x def g(): exec "x=3" return x print g() f() prints 3, not 7. PS: this improve backw-compatibility but the PEP is ambiguous or block concept does not imply nested definitions(?). This affects only special cases but it is quite strange in presence of nested scopes, having decl that do not extend to inner scopes.
Hi. Is the following true?
PEP227 states: """ If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. """
but this is a bit ambiguous, because the global decl (I imagine for backw-compatibility) does not affect the code blocks of nested (func) definitions. So
x=7 def f(): global x def g(): exec "x=3" return x print g()
f()
prints 3, not 7.
Unclear whether this should change. The old rule can also be read as "you have to repeat 'global' for a variable in each scope where you intend to assign to it".
PS: this improve backw-compatibility but the PEP is ambiguous or block concept does not imply nested definitions(?). This affects only special cases but it is quite strange in presence of nested scopes, having decl that do not extend to inner scopes.
--Guido van Rossum (home page: http://www.python.org/~guido/)
I didn't want to start a discussion, I was more concerned if I got the semantic (that I should impl) right. So: x=7 def f(): x=1 def g(): global x def h(): return x return h() return g() will print 1. Ok. regards. PS: I tried this with a2 and python just died, I imagine, this has been fixed.
I didn't want to start a discussion, I was more concerned if I got the semantic (that I should impl) right. So: x=7 def f(): x=1 def g(): global x def h(): return x return h() return g()
and then print f() as main, right?
will print 1. Ok.
regards.
Argh! I honestly don't know what this ought to do. Under the rules as I currently think of them this would print 1. But that's at least surprising, so maybe we'll have to revisit this. Jeremy, also please note that if I add "from __future__ import nested_scopes" to the top, this dumps core, saying: lookup 'x' in g 2 -1 Fatal Python error: com_make_closure() Aborted (core dumped) Maybe you can turn this into a regular error? <0.5 wink>
PS: I tried this with a2 and python just died, I imagine, this has been fixed.
Seems so. :-) --Guido van Rossum (home page: http://www.python.org/~guido/)
[Samuele Pedroni]
x=7 def f(): global x def g(): exec "x=3" return x print g()
f()
prints 3, not 7.
Note the the Ref Man (section on the global stmt) adds some more wrinkles: ... global is a directive to the parser. It applies only to code parsed at the same time as the global statement. In particular, a global statement contained in an exec statement does not affect the code block containing the exec statement, and code contained in an exec statement is unaffected by global statements in the code containing the exec statement. The same applies to the eval(), execfile() and compile() functions.
Quoth the Samuele Pedroni:
In particular, a global statement contained in an exec statement does not affect the code block containing the exec statement, and code contained in an exec statement is unaffected by global statements in the code containing the exec statement.
I think this is broken. As long as we're going to allow exec-with-1-arg to implicitly mess with the current namespace, names in the exec'ed statement should have the same meanings as they do in the surrounding statically-compiled code. So, global statements in the surrounding scope should be honoured in the exec'ed statement, and global statements should be disallowed within the exec'ed statement. Better still, get rid of both exec-with-1-arg and locals() altogether... Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+
Quoth the Samuele Pedroni:
In particular, a global statement contained in an exec statement does not affect the code block containing the exec statement, and code contained in an exec statement is unaffected by global statements in the code containing the exec statement.
I think this is broken. As long as we're going to allow exec-with-1-arg to implicitly mess with the current namespace, names in the exec'ed statement should have the same meanings as they do in the surrounding statically-compiled code.
So, global statements in the surrounding scope should be honoured in the exec'ed statement, and global statements should be disallowed within the exec'ed statement.
Better still, get rid of both exec-with-1-arg and locals() altogether...
That's my plan, so I suppose we should not bother to "fix" the broken behavior that has been around from the start. --Guido van Rossum (home page: http://www.python.org/~guido/)
x=7 def f(): global x def g(): exec "x=3" return x print g()
f()
prints 3, not 7.
I've been meaning to reply to your original post on this subject, which actually addresses two different issues -- global and exec. The example above will fail with a SyntaxError in the nested_scopes future, because of exec in the presence of a free variable. The error message is bad, because it says that exec is illegal in g because g contains nested scopes. I may not get to fix that before the beta. The reasoning about the error here is, as usual with exec, that name binding is a static or compile-time property of the program text. The use of hyper-dynamic features like import * and exec are not allowed when they may interfere with static resolution of names. Buy that? Jeremy
Hi.
x=7 def f(): global x def g(): exec "x=3" return x print g()
f()
prints 3, not 7.
I've been meaning to reply to your original post on this subject, which actually addresses two different issues -- global and exec. The example above will fail with a SyntaxError in the nested_scopes future, because of exec in the presence of a free variable. The error message is bad, because it says that exec is illegal in g because g contains nested scopes. I may not get to fix that before the beta.
The reasoning about the error here is, as usual with exec, that name binding is a static or compile-time property of the program text. The use of hyper-dynamic features like import * and exec are not allowed when they may interfere with static resolution of names.
Buy that? Yes I buy that. (I had tried it with the old a2) So also this code will raise an error or I'm not understanding the point and the error happens because of the global decl?
# top-level def g(): exec "x=3" return x For me is ok, but that kills many naive uses of exec, I'm wondering if it does not make more sense to directly take the next big step and issue an error (under future nested_scopes) for *all* the uses of exec without in. Because every use of a builtin will cause the error... regards
"SP" == Samuele Pedroni <pedroni@inf.ethz.ch> writes:
SP> # top-level SP> def g(): SP> exec "x=3" SP> return x At the top-level, there is no closure created by the enclosing scope is not a function scope. I believe that's the right thing to do, except that the exec "x=3" also assign to the global. I'm not sure if there is a strong justification for allowing this form, except that it is the version of exec that is most likely to occur in legacy code. Jeremy
"SP" == Samuele Pedroni <pedroni@inf.ethz.ch> writes:
SP> # top-level SP> def g(): SP> exec "x=3" SP> return x
At the top-level, there is no closure created by the enclosing scope is not a function scope. I believe that's the right thing to do, except that the exec "x=3" also assign to the global.
I'm not sure if there is a strong justification for allowing this form, except that it is the version of exec that is most likely to occur in legacy code.
Unfortunately this used to work, using a gross hack: when an exec (or import *) was present inside a function, the namespace semantics *for that function* was changed to the pre-0.9.1 semantics, where all names are looked up *at run time* first in the locals then in the globals and then in the builtins. I don't know how common this is -- it's pretty fragile. If there's a great clamor, we can put this behavior back after b1 is released. --Guido van Rossum (home page: http://www.python.org/~guido/)
SP> # top-level SP> def g(): SP> exec "x=3" SP> return x
[me]
Unfortunately this used to work, using a gross hack: when an exec (or import *) was present inside a function, the namespace semantics *for that function* was changed to the pre-0.9.1 semantics, where all names are looked up *at run time* first in the locals then in the globals and then in the builtins.
I don't know how common this is -- it's pretty fragile. If there's a great clamor, we can put this behavior back after b1 is released.
I spoke too soon. It just works in the latest 2.1b1. Or am I missing something? --Guido van Rossum (home page: http://www.python.org/~guido/)
"GvR" == Guido van Rossum <guido@digicool.com> writes:
SP> # top-level SP> def g(): SP> exec "x=3" return x
GvR> [me]
Unfortunately this used to work, using a gross hack: when an exec (or import *) was present inside a function, the namespace semantics *for that function* was changed to the pre-0.9.1 semantics, where all names are looked up *at run time* first in the locals then in the globals and then in the builtins.
I don't know how common this is -- it's pretty fragile. If there's a great clamor, we can put this behavior back after b1 is released.
GvR> I spoke too soon. It just works in the latest 2.1b1. Or am I GvR> missing something? The nested scopes rules don't kick in until you've got one function nested in another. The top-level namespace is treated differently that other function namespaces. If a function is defined at the top-level then all its free variables are globals. As a result, the old rules still apply. Since class scopes are ignored for nesting, methods defined in top-level classes are handled the same way. I'm not completely sure this makes sense, although it limits code breakage; most functions are defined at the top-level or in classes! I think it is fairly clear, though. Jeremy
SP> # top-level SP> def g(): SP> exec "x=3" return x
GvR> [me]
Unfortunately this used to work, using a gross hack: when an exec (or import *) was present inside a function, the namespace semantics *for that function* was changed to the pre-0.9.1 semantics, where all names are looked up *at run time* first in the locals then in the globals and then in the builtins.
I don't know how common this is -- it's pretty fragile. If there's a great clamor, we can put this behavior back after b1 is released.
GvR> I spoke too soon. It just works in the latest 2.1b1. Or am I GvR> missing something?
The nested scopes rules don't kick in until you've got one function nested in another. The top-level namespace is treated differently that other function namespaces. If a function is defined at the top-level then all its free variables are globals. As a result, the old rules still apply.
This doesn't make sense. If the free variables were truely considered globals, the reference to x would raise a NameError, because the exec doesn't define it at the global level -- it defines it at the local level. So apparently you are generating LOAD_NAME instead of LOAD_GLOBAL for free variables in toplevel functions. Oh well, this does the job!
Since class scopes are ignored for nesting, methods defined in top-level classes are handled the same way.
I'm not completely sure this makes sense, although it limits code breakage; most functions are defined at the top-level or in classes! I think it is fairly clear, though.
Yeah, it's pretty unlikely that there will be much code breakage of this form: def f(): def g(): exec "x = 1" return x (Hm, trying this I see that it generates a warning, but with the wrong filename. I'll see if I can use symtable_warn() here.) --Guido van Rossum (home page: http://www.python.org/~guido/)
"GvR" == Guido van Rossum <guido@digicool.com> writes:
The nested scopes rules don't kick in until you've got one function nested in another. The top-level namespace is treated differently that other function namespaces. If a function is defined at the top-level then all its free variables are globals. As a result, the old rules still apply.
GvR> This doesn't make sense. If the free variables were truely GvR> considered globals, the reference to x would raise a NameError, GvR> because the exec doesn't define it at the global level -- it GvR> defines it at the local level. So apparently you are GvR> generating LOAD_NAME instead of LOAD_GLOBAL for free variables GvR> in toplevel functions. Oh well, this does the job! Actually, I only generate LOAD_NAME for unoptimized, top-level function namespaces. These are exactly the old rules and I avoided changing them for top-level functions, except when they contained a nested function. If we eliminate exec without "in," this is yet another problem that goes away. Jeremy
[Jeremy]
The nested scopes rules don't kick in until you've got one function nested in another. The top-level namespace is treated differently that other function namespaces. If a function is defined at the top-level then all its free variables are globals. As a result, the old rules still apply.
GvR> This doesn't make sense. If the free variables were truely GvR> considered globals, the reference to x would raise a NameError, GvR> because the exec doesn't define it at the global level -- it GvR> defines it at the local level. So apparently you are GvR> generating LOAD_NAME instead of LOAD_GLOBAL for free variables GvR> in toplevel functions. Oh well, this does the job!
[Jeremy]
Actually, I only generate LOAD_NAME for unoptimized, top-level function namespaces. These are exactly the old rules and I avoided changing them for top-level functions, except when they contained a nested function.
Aha.
If we eliminate exec without "in," this is yet another problem that goes away.
But that's for another release... That will probably get a lot of resistance from some category of users! So it's fine for now. Thanks, Jeremy! Great job! --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (5)
-
Greg Ewing
-
Guido van Rossum
-
Jeremy Hylton
-
Samuele Pedroni
-
Tim Peters