[New-bugs-announce] [issue17853] class construction name resolution broken in functions

Ethan Furman report at bugs.python.org
Sat Apr 27 10:10:01 CEST 2013


New submission from Ethan Furman:

In playing with metaclasses for the ongoing Enum saga, I tried having the metaclass insert an object into the custom dict (aka namespace) returned by __prepare__; this object has the same name as the to-be-created class.

An example:

class Season(Enum):
    SPRING = Season()
    SUMMER = Season()
    AUTUMN = Season()
    WINTER = Season()

When this executes as top level code it works beautifully.

However, if you have the exact same definition in a function, Bad Things happen:

---------------------------------------
--> def test():
...   class Season(Enum):
...     SPRING = Season()
... 
--> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
  File "<stdin>", line 3, in Season
NameError: free variable 'Season' referenced before assignment in enclosing scope
---------------------------------------

So I tried creating a dummy variable to see if it would be worked around:

---------------------------------------
--> def test():
...   Season = None
...   class Season(Enum):
...     SPRING = Season()
... 
--> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in test
  File "<stdin>", line 4, in Season
TypeError: 'NoneType' object is not callable
---------------------------------------

Finally I inserted the object using a different name, and also printed 'locals()' just to see what was going on:

---------------------------------------
--> def test():
...   class Season(Enum):
...     print(locals())
...     SPRING = S()
... 
--> test()
{'S': <class 'aenum.Season'>, 'Season': <class 'aenum.Season'>, '__module__': '__main__', '__qualname__': 'test.<locals>.Season', '__locals__': {...}}
---------------------------------------

and an actual (albeit extremely ugly) work around:

---------------------------------------
>>> def test():
...   class Season(Enum):
...     Season = locals()['Season']
...     SPRING = Season()
...   print(Season)
... 
>>> test()
Season(SPRING=1)
---------------------------------------

It seems that the function namespace is seriously messing with the class namespace.

----------
components: Interpreter Core
messages: 187892
nosy: stoneleaf
priority: normal
severity: normal
status: open
title: class construction name resolution broken in functions
type: behavior
versions: Python 3.2, Python 3.3

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue17853>
_______________________________________


More information about the New-bugs-announce mailing list