<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body text="#330033" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">On 5/6/2013 6:26 PM, Ethan Furman
      wrote:<br>
    </div>
    <blockquote cite="mid:51885860.3090702@stoneleaf.us" type="cite">On
      05/05/2013 01:01 AM, Glenn Linderman wrote:
      <br>
      <blockquote type="cite">
        <br>
        The bigger problem is that the arithmetic on enumeration items,
        which seems like it should be inherited from NamedInt
        <br>
        (and seems to be, because the third value from each print is a
        NamedInt), doesn't pick up "x" or "y", nor does it pick
        <br>
        up "the-x" or "the-y", but rather, it somehow picks up the str
        of the value.
        <br>
      </blockquote>
      <br>
      Indeed, the bigger problem is that we ended up have an (NamedInt,
      Enum) wrapping a NamedInt, so we had both NEI.x._intname /and/
      NEI.x.value._intname, and it was just one big mess.
      <br>
      <br>
      But I think it is solved.  Try the new code.  Here's what your
      example should look like:
      <br>
    </blockquote>
    <br>
    OK. I notice you changed some super()s to specific int calls; I
    think I understand why, having recently reread about the specific
    problem that super() solves regarding diamond inheritance, and with
    that understanding, it is clear that super() is not always the right
    thing to use, particularly when unrelated classes may still have
    particular methods with name clashes (dunder methods would commonly
    have the same names in unrelated classes).  So my use of super
    likely contributed to the multiple wrappings that you allude to
    above, although I haven't (yet) tried to figure out the exact
    details of how that happened.<br>
    <br>
    <blockquote cite="mid:51885860.3090702@stoneleaf.us" type="cite">
      <br>
          class NamedInt( int ):
      <br>
              def __new__( cls, *args, **kwds ):
      <br>
                  _args = args
      <br>
                  name, *args = args
      <br>
                  if len( args ) == 0:
      <br>
                      raise TypeError("name and value must be
      specified")
      <br>
                  self = int.__new__( cls, *args, **kwds )
      <br>
                  self._intname = name
      <br>
                  return self
      <br>
              @property
      <br>
              def __name__( self ):
      <br>
                  return self._intname
      <br>
              def __repr__( self ):
      <br>
                  # repr() is updated to include the name and type info
      <br>
                  return "{}({!r}, {})".format(type(self).__name__,
      <br>
                                               self.__name__,
      <br>
                                               int.__repr__(self))
      <br>
              def __str__( self ):
      <br>
                  # str() is unchanged, even if it relies on the repr()
      fallback
      <br>
                  base = int
      <br>
                  base_str = base.__str__
      <br>
                  if base_str.__objclass__ is object:
      <br>
                      return base.__repr__(self)
      <br>
                  return base_str(self)
      <br>
              # for testing, we only define one operator that propagates
      expressions
      <br>
              def __add__(self, other):
      <br>
                  temp = int( self ) + int( other )
      <br>
                  if isinstance( self, NamedInt ) and isinstance( other,
      NamedInt ):
      <br>
                      return NamedInt(
      <br>
                          '({0} + {1})'.format(self.__name__,
      other.__name__),
      <br>
                          temp )
      <br>
                  else:
      <br>
                      return temp
      <br>
      <br>
          class NEI( NamedInt, Enum ):
      <br>
              x = ('the-x', 1 )
      <br>
              y = ('the-y', 2 )
      <br>
    </blockquote>
    <br>
    I had tried this sort of constructor, thinking it should work, but
    couldn't tell that it helped or hindered, but it probably took
    eliminating the super() problem earlier, and likely your
    preservation of __new__ in your ref435 changes, to enable this
    syntax to do what I expected it might.  This certainly does allow
    the name definitions to be better grouped, even though still
    somewhat redundant.<br>
    <br>
    It may take a subclass of the enum_type, as Nick was suggesting, to
    make the NamedInt and the enumeration member actually share a single
    name... but this (after fleshing out NamedInt with more operators)
    would be a functional method of producing enumerations for the
    various flag parameters in the Python API (that are mostly inherited
    from wrapped C APIs, I suppose... at least, I haven't found a need
    or benefit of creating flag parameters in new Python APIs that I
    have created).<br>
    <br>
    <blockquote cite="mid:51885860.3090702@stoneleaf.us" type="cite">   
      NEI.x + NEI.y
      <br>
    </blockquote>
    <br>
    And this works as expected, now. Can't say I still fully understand
    the changes, but the test case works, and the constructors for the
    NamedInt inside the NEI class works, so this is pretty much what I
    was hoping to be able when I started down this path... but since it
    found some issues that you were able to fix in ref435, I guess I
    wasn't totally wasting your time presenting the issue. Thanks for
    investigating, and fixing, rather than blowing it off, even given my
    amateurish presentation.<br>
    <br>
    And I should have called this NIE, not NEI, because it was intended
    to stand for NamedIntEnum... but it is just a name, so doesn't
    affect the functionality.<br>
    <br>
    <br>
    N.B.  In your latest ref435.py code, line 105, should be "An Enum
    class _is_ final..." rather than "in".<br>
  </body>
</html>