<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>