Issue532860
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2002-03-21 01:27 by spiv, last changed 2022-04-10 16:05 by admin. This issue is now closed.
Messages (5) | |||
---|---|---|---|
msg9853 - (view) | Author: Andrew Bennetts (spiv) | Date: 2002-03-21 01:27 | |
This fails with a NameError: def f(x) class Private: x = x return Private f(17) But this works: def f(x): y = x class Private: x = y return Private f(17) But this fails: def f(x): y = x class Private: y = y return Private f(17) See also the newsgroup thread: http://groups.google.com/groups?hl=en&ie=ISO-8859-1&oe=ISO-8859-1&threadm=Xns (All tested on Python 2.2 on Win2k) |
|||
msg9854 - (view) | Author: Jeremy Hylton (jhylton) | Date: 2002-04-19 16:39 | |
Logged In: YES user_id=31392 This is actually working as intended, although the reference manual no longer describes this case at all. It has been a long standing "feature" of Python that module and class blocks use the LOAD_NAME opcode, which has weird scoping rules. The documentation should be updated to describe the cases in which LOAD_NAME is used and its behavior. (It checks locals, globals, builtins in that order, and never raises a NameError unless the name isn't found in any of those namespaces. In particular, an unbound local is simply ignored.) I don't actually know what these rules are used. Guido-- should we get rid of LOAD_NAME? |
|||
msg9855 - (view) | Author: Andrew Bennetts (spiv) | Date: 2002-04-22 09:31 | |
Logged In: YES user_id=50945 Apologies for re-opening the bug. This behaviour still seems like a bug to me, because while this dies: >>> def f(x): ... class Private: ... x = x ... return Private ... >>> f(17) Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in f File "<stdin>", line 3, in Private NameError: name 'x' is not defined This works: >>> x = 1 >>> class C: ... x = x ... >>> C() <__main__.C instance at 0x806aeac> Actually, having the global "x = 1" also makes the first case work. This seems inconsistent enough to me to warrant it being called a bug, regardless of the underlying implementation details (which I know little of). I'd expect it work in both cases, or neither case. Feel free to close the bug again if you disagree :) It's quite easy to work around, so I'm not worried greatly by it. (workaround: def f(x): class Private: pass Private.x = x return Private ) |
|||
msg9856 - (view) | Author: Jeremy Hylton (jhylton) | Date: 2002-04-22 17:25 | |
Logged In: YES user_id=31392 The behavior bugs me too, but I don't expect it will get fixed because of the need for backwards compatibility. The local namespace for classes, modules, and functions that contain exec or import * are searched using the LOAD_NAME opcode. This opcode implements the old locals, globals, builtin search for a name using dict lookup. If the dict lookup fails at any level, the next level up is searched. This means an unbound local error will never occur in a class block, because the dict lookup just returns NULL and the search proceeds to globals. If anything, the bug is the was "x=x" behaves at the class level, but I'm loathe to change it. It will probably break existing code and will require substantial implementation effort (I think) because class namespaces aren't implemented using the same technique as a function namespace. I'd rather document the existing wart and live with it. In particular, I might document it with the following weasle words: "The result of reference an unbound local name in a class block is undefined." |
|||
msg9857 - (view) | Author: Jeremy Hylton (jhylton) | Date: 2002-04-22 18:43 | |
Logged In: YES user_id=31392 Indeed, after conversation with GvR, we are in agreement that it would break too much old code to "fix" this. Just don't write code that abuses the wart at the module level, and you'll never feel its a bug when nested inside a function <0.1 wink>. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:05:07 | admin | set | github: 36300 |
2002-03-21 01:27:24 | spiv | create |