Message187892
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. |
|
Date |
User |
Action |
Args |
2013-04-27 08:10:01 | ethan.furman | set | recipients:
+ ethan.furman |
2013-04-27 08:10:01 | ethan.furman | set | messageid: <1367050201.95.0.307419620832.issue17853@psf.upfronthosting.co.za> |
2013-04-27 08:10:01 | ethan.furman | link | issue17853 messages |
2013-04-27 08:10:01 | ethan.furman | create | |
|