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 <rep...@bugs.python.org> <http://bugs.python.org/issue17853> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com