Forward references are now implemented (https://github.com/anntzer/enum).  They require an explicit declaration, à la<br><br>class C(Enum, declaration=...):<br>    B = ...<br>    A = {1: B}<br>    B = {1: A}<br><br>I had implemented a version where the initial declaration wasn't needed, but as mentioned in previous enum-related threads this can create many problems.  For example, consider<br><br>class C(Enum):<br>    A = {1: B}; B = {1: A}<br>    @property<br>    def also_value(self): return self.value<br><br>how is Python supposed to know that when it tries to resolve "B" in the class dict, it must create a new member, but when it tries to resolve "property" in the class dict and doesn't find it, it must look in the enclosing scope?  You can decide that a name lookup creates a new member if the name isn't defined in the enclosing scope either (I implemented this using sys._getframe in a previous commit of my fork) but this leads to other (somewhat contrieved) problems:<br><br>x = 1<br>class C(Enum):<br>    y = x # <- what is this supposed to mean?<br>    x = 2<br><br>Note that even AST macros don't (fully) this issue because you can't really even know the list of all names that are defined in the class body:<br><br>x = 1<br>def inject(**kwargs):<br>    for k, v in kwargs.items(): sys._getframe(1).f_locals[k] = v # interestingly using dict.update does not trigger the use-defined __setitem__<br>class C(Enum):<br>    y=x # <- ???<br>    inject_value(x=2)<br><br>Antony<br><br>On Monday, July 8, 2013 6:03:27 PM UTC-7, Haoyi Li wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr">> <span style="font-family:arial,sans-serif;font-size:13px">then the other methods can either dereference the name with an __getitem__ look-up, or the class can be post-processed with a decorator to change the strings back to actual members... hmmm, maybe a post_process hook in the metaclass would make sense?</span><div>


<br></div><div>Having real strings be part of the enums data members is a pretty common thing, and working through and trying to identify the linkage-strings from normal-strings seems very magical to me. Is there some metaclass-magic way to intercept the usage of A, to instead put the enum instance there?</div>


<div><br></div><div>Also, for this to be useful for your described use case, (state machines yay!) you'd probably want to be able to define back/circular references, which i think isn't currently possible. The obvious thing to do would be to somehow make the RHS of the assignments lazy, which would allow out-of-order and circular assignments with a very nice, unambigious:</div>

<div><br></div><div>
<span style="font-family:arial,sans-serif;font-size:13px">class StateMachine(Enum):</span></div><div>    "Useless ping-pong state machine"<br style="font-family:arial,sans-serif;font-size:13px"><span style="font-family:arial,sans-serif;font-size:13px">    A = {1: B}</span><br style="font-family:arial,sans-serif;font-size:13px">


<span style="font-family:arial,sans-serif;font-size:13px">    B = {1: A}</span><br></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">But short of using macros to do an AST transform, I don't know if such a thing is possible at all.</span></div>

<div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">-Haoyi</span></div></div><div><br><br><div class="gmail_quote">

On Tue, Jul 9, 2013 at 8:12 AM, Ethan Furman <span dir="ltr"><<a href="javascript:" target="_blank" gdf-obfuscated-mailto="2h9tjFfeKeEJ">et...@stoneleaf.us</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div>On 07/08/2013 02:27 PM, Antony Lee wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Currently, during the execution of the body of the Enum declaration, member names are bound to the values, not to the<br>
Enum members themselves.  For example<br>
<br>
class StateMachine(Enum):<br>
     A = {}<br>
     B = {1: A} # e.g. a transition table<br>
<br>
StateMachine.B[1] == {}, when one could have expected StateMachine.B[1] == StateMachine.A<br>
<br>
It seems to me that a behavior where member names are bound to the members instead of being bound to the values is more<br>
useful, as one can easily retrieve the values from the members but not the other way round (at least during the<br>
execution of class body).<br>
<br>
Initially, I thought that this could be changed by modifying _EnumDict, so that its __setitem__ method sets the member<br>
in the dict, instead of the value, but in fact this doesn't work because while the values are being set in the _EnumDict<br>
the class itself doesn't exist yet (and for good reason: the __init__ and __new__ methods may be defined later but there<br>
is no way to know that).  However, a possible solution could to momentarily create Enum members as instances of some<br>
dummy class, and then later, after execution of class body has completed, change the members' class to the actual Enum<br>
and initialize them as needed (if an __init__ or a __new__ are actually defined).  Well, there are limitations with this<br>
approach (e.g. the members are not fully initialized before class body finishes to execute) but this seems better than<br>
the current behavior(?)<br>
</blockquote>
<br></div></div>
Part of the problem here would be maintaining the linkage when the temp enum object from _EnumDict was translated into an actual Enum member.<br>
<br>
One possible work around is to store the name of the member instead:<br>
<br>
  class StateMachine(Enum):<br>
      A = {}<br>
      B = {1:'A'}<br>
<br>
then the other methods can either dereference the name with an __getitem__ look-up, or the class can be post-processed with a decorator to change the strings back to actual members... hmmm, maybe a post_process hook in the metaclass would make sense?<br>


<br>
--<br>
~Ethan~<br>
______________________________<u></u><wbr>_________________<br>
Python-ideas mailing list<br>
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="2h9tjFfeKeEJ">Python...@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/python-ideas" target="_blank">http://mail.python.org/<u></u>mailman<wbr>/listinfo/python-ideas</a><br>
</blockquote></div><br></div>
</blockquote>