You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2002-04-22.18:43:12.000>created_at=<Date2002-03-21.01:27:24.000>labels= ['interpreter-core']
title='NameError assigning to class in a func'updated_at=<Date2002-04-22.18:43:12.000>user='https://bugs.python.org/spiv'
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?
spiv commented on Apr 22, 2002
spivmannequin
MannequinAuthor
More actions
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:
>>> deff(x):
... classPrivate:
... 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
>>> classC:
... 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
)
jhylton commented on Apr 22, 2002
jhyltonmannequin
Mannequin
More actions
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."
jhylton commented on Apr 22, 2002
jhyltonmannequin
Mannequin
More actions
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>.
Activity
spiv commentedon Mar 21, 2002
This fails with a NameError:
But this works:
But this fails:
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)
jhylton commentedon Apr 19, 2002
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?
spiv commentedon Apr 22, 2002
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:
This works:
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
)
jhylton commentedon Apr 22, 2002
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."
jhylton commentedon Apr 22, 2002
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>.