[Python-bugs-list] [ python-Bugs-532860 ] NameError assigning to class in a func

noreply@sourceforge.net noreply@sourceforge.net
Mon, 22 Apr 2002 02:31:58 -0700


Bugs item #532860, was opened at 2002-03-21 12:27
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=532860&group_id=5470

Category: Python Interpreter Core
Group: Python 2.2
>Status: Open
Resolution: Wont Fix
Priority: 5
Submitted By: Andrew Bennetts (spiv)
Assigned to: Jeremy Hylton (jhylton)
Summary: NameError assigning to class in a func

Initial Comment:
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)



----------------------------------------------------------------------

>Comment By: Andrew Bennetts (spiv)
Date: 2002-04-22 19:31

Message:
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
)


----------------------------------------------------------------------

Comment By: Jeremy Hylton (jhylton)
Date: 2002-04-20 02:39

Message:
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?


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=532860&group_id=5470