[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