<div dir="ltr">On 5 May 2013 11:22, Tim Delaney <span dir="ltr"><<a href="mailto:timothy.c.delaney@gmail.com" target="_blank">timothy.c.delaney@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="im">On 5 May 2013 10:49, Eli Bendersky <span dir="ltr"><<a href="mailto:eliben@gmail.com" target="_blank">eliben@gmail.com</a>></span> wrote:<br>
</div><div class="gmail_extra"><div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote"><div>On Sat, May 4, 2013 at 4:27 PM, Tim Delaney <span dir="ltr"><<a href="mailto:timothy.c.delaney@gmail.com" target="_blank">timothy.c.delaney@gmail.com</a>></span> wrote:<br>



<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Typo line 171: <Colro.blue: 3><div><br>
</div></div></blockquote><div><br></div></div><div>Fixed, thanks.<br>


<br> <br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>One thing I'd like to be clear in the PEP about is whether enum_type and _EnumDict._enum_names should be documented, or whether they're considered implementation details.</div>




<div><br></div></div></blockquote><div><br></div></div><div>No, they should not. Not only are they implementation details, they are details of the *reference implementation*, not the actual stdlib module. The reference implementation will naturally serve as a basis for the stdlib module, but it still has to undergo a review in which implementation details can change. Note that usually we do not document implementation details of stdlib modules, but this doesn't prevent some people from using them if they really want to.</div>

</div></div></div></blockquote><div><br></div></div><div>I think it would be useful to have some guaranteed method for a sub-metaclass to get the list of enum keys before calling the base class __new__. Not being able to do so removes a large number of possible extensions (like auto-numbering).</div>
</div></div></div></blockquote><div> </div><div style> I've been able to achieve the auto-numbering without relying on the internal implementation at all (with a limitation), with a single change to enum_type.__new__. My previous patch was slightly wrong - fix below as well. All existing tests pass. BTW, for mix-ins it's required that they have __slots__ = () - might want to mention that in the PEP.</div>
<div style><br></div><div style><div><div><div>diff -r 758d43b9f732 ref435.py</div><div>--- a/ref435.py<span class="" style="white-space:pre">  </span>Fri May 03 18:59:32 2013 -0700</div><div>+++ b/ref435.py<span class="" style="white-space:pre">      </span>Sun May 05 13:10:11 2013 +1000</div>
<div>@@ -116,7 +116,17 @@</div><div>             if bases[-1] is Enum:</div><div>                 obj_type = bases[0]</div><div>             else:</div><div>-                obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int, Enum, object)</div>
<div>+                obj_type = None</div><div>+</div><div>+                for base in bases:</div><div>+                    for c in base.__mro__:</div><div>+                        if not issubclass(c, Enum):</div><div>
+                            obj_type = c</div><div>+                            break</div><div>+</div><div>+                    if obj_type is not None:</div><div>+                        break</div><div>+</div><div>         else:</div>
<div>             obj_type = object</div><div>         # save enum items into separate mapping so they don't get baked into</div><div>@@ -142,6 +152,7 @@</div><div>                 if obj_type in (object, Enum):</div>
<div>                     enum_item = object.__new__(enum_class)</div><div>                 else:</div><div>+                    value = obj_type.__new__(obj_type, value)</div><div>                     enum_item = obj_type.__new__(enum_class, value)</div>
<div>                 enum_item._value = value</div><div>                 enum_item._name = e</div></div></div><div><br></div><div style>Implementation:<br></div></div><div style><br></div><div style><div>class AutoInt(int):</div>
<div>    __slots__ = ()  # Required</div><div><br></div><div>    def __new__(cls, value):</div><div>        if value is Ellipsis:</div><div>            try:</div><div>                i = cls._auto_number</div><div>            except AttributeError:</div>
<div>                i = cls._auto_number = 0</div><div><br></div><div>        else:</div><div>            i = cls._auto_number = value</div><div><br></div><div>        cls._auto_number += 1</div><div>        return int.__new__(cls, i)</div>
<div><br></div><div>class AutoIntEnum(AutoInt, IntEnum):<br></div><div>    pass</div><div><br></div><div>class TestAutoIntEnum(AutoIntEnum):</div><div>    a = ...</div><div>    b = 3</div><div>    c = ...</div><div><br></div>
<div>print(TestAutoIntEnum, list(TestAutoIntEnum))</div><div><br></div><div><div>---------- Run ----------</div><div><Enum 'TestAutoIntEnum'> [<TestAutoIntEnum.a: 0>, <TestAutoIntEnum.b: 3>, <TestAutoIntEnum.c: 4>]<br>
</div><div></div></div><div style><br></div><div style>The implementation is not quite as useful - there's no immediately-obvious way to have an auto-numbered enum that is not also an int enum e.g. if you define class AutoNumberedEnum(AutoInt, Enum) it's still an int subclass.</div>
<div style><br></div><div style>Tim Delaney</div></div></div></div></div>