classification
Title: listcomp with nested classes
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.2, Python 3.3
process
Status: closed Resolution: duplicate
Dependencies: Superseder: Comprehensions in a class definition mostly cannot access class variable
View: 11796
Assigned To: Nosy List: alex, flox, hynek, josmiley, r.david.murray, westley.martinez
Priority: normal Keywords:

Created on 2012-05-31 21:40 by josmiley, last changed 2012-06-01 15:39 by flox. This issue is now closed.

Messages (5)
msg162022 - (view) Author: josmiley (josmiley) Date: 2012-05-31 21:40
# this runs with python2.7, not with python3.2
class Foo(object):

    class Bar(object):
        pass

    Attr = [Bar()for n in range(10)]

# solved in this way ...
class Foo(object):

    class Bar(object):
        pass

    Attr = []
    for n in range(10): Attr.append(Bar())
msg162023 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012-05-31 21:53
Simpler test case:

class A:
   x = 42
   y = [x for _ in '1']


The semantics of list comprehension changed with Python 3.
However, I do not see this specific behavior documented somewhere.

http://docs.python.org/dev/whatsnew/3.0.html#changed-syntax
msg162024 - (view) Author: Westley Martínez (westley.martinez) * Date: 2012-05-31 22:04
$ python
Python 3.2.3 (default, Apr 23 2012, 23:35:30) 
[GCC 4.7.0 20120414 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
...     x = 42
...     y = [x for _ in '1']
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in A
  File "<stdin>", line 3, in <listcomp>
NameError: global name 'x' is not defined
>>> x = 42
>>> class A:
...     x = 12
...     y = [x for _ in '1']
... 
>>> A.y
[42]

It seems that the list comprehension is looking at the module's scope as opposed to the class scope.  This definitely seems incorrect to me.
msg162026 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-05-31 22:07
This is doubtless a result of the way the class namespace scope is handled, coupled with the fact that in Python3 list comprehensions have a local scope.  The class scope is a somewhat unique beast.  I agree that this is unfortunate, but I have a feeling that doing anything about it is distinctly non-trivial.
msg162077 - (view) Author: Florent Xicluna (flox) * (Python committer) Date: 2012-06-01 15:39
This is a duplicate of issue 11796.

See also issue 13557:
http://bugs.python.org/issue13557#msg154174

For Python 3, a list comprehension defines a block pretty much like the method definition during the class creation:

class x:
    x = 1
    def incx():
        return x + 1
    print(incx())

 ==> raises NameError too
History
Date User Action Args
2012-06-01 15:39:55floxsetstatus: open -> closed
superseder: Comprehensions in a class definition mostly cannot access class variable
resolution: duplicate
messages: + msg162077
2012-05-31 23:34:03hyneksetnosy: + hynek
2012-05-31 22:07:51r.david.murraysetnosy: + r.david.murray
messages: + msg162026
2012-05-31 22:04:02westley.martinezsetnosy: + westley.martinez
messages: + msg162024
2012-05-31 22:00:13alexsetnosy: + alex
2012-05-31 21:53:08floxsetversions: + Python 3.3
nosy: + flox

messages: + msg162023

components: + Interpreter Core
2012-05-31 21:40:54josmileycreate