[Python-Dev] PEP 435 - ref impl disc 2

Ethan Furman ethan at stoneleaf.us
Tue May 14 04:36:56 CEST 2013


On 05/10/2013 10:15 PM, Glenn Linderman wrote:
>
> So it is quite possible to marry the two, as Ethan helped me figure out using an earlier NamedInt class:
>
> class NIE( IntET, Enum ):
>      x = ('NIE.x', 1)
>      y = ('NIE.y', 2)
>      z = ('NIE.z', 4)
>
> and then expressions involving members of NIE (and even associated integers) will be tracked... see demo1.py.
>
> But the last few lines of demo1 demonstrate that NIE doesn't like, somehow, remember that its values, deep down under
> the covers, are really int.  And doesn't even like them when they are wrapped into IntET objects.  This may or may not
> be a bug in the current Enum implementation.

[demo1.py excerpt]
     print( repr( NIE1( 1 ) + NIE1(2)))
     print( repr( NIE1( IntET('NIE1.x', 1 )) + NIE1(2)))


> So the questions are:
> 1) Is there a bug in ref435 Enum that makes demo1 report errors instead of those lines working?

Nope.

> 2) Is something like demo2 interesting to anyone but me? Of course, I think it would be great for reporting flag values
> using names rather than a number representing combined bit fields.

No idea.  ;)

> 3) I don't see a way to subclass the ref435 EnumMeta except by replacing the whole __new__ method... does this mechanism
> warrant a slight refactoring of EnumMeta to make this mechanism easier to subclass with less code redundancy?

I've broken it down to make subclassing easier.

> 4) Or is it simple enough and useful enough to somehow make it a feature of EnumMeta, enabled by a keyword parameter?

Probably not.

> 5) All this is based on "IntET"... which likely suffices for API flags parameters... but when I got to __truediv__ and
> __rtruediv__, which don't return int, then I started wondering how to write a vanilla ET class that inherits from
> "number" instead of "int" or "float"? One could, of course, make cooperating classes FloatET and DecimalET .... is this
> a language limitation, or is there more documentation I haven't read? :)   (I did read footnote [1] of
> <http://docs.python.org/3/reference/datamodel.html#emulating-numeric-types>, and trembled.)

Sounds like a fun project (for some value of fun ;)


Okay, sorry for the long delay.

What it comes down to is if you want to marry two complex types together, you may have to be the counselor as well. ;)

Here's your code, revamped.  I did make a slight change in the meta --  I moved the name assignment above the __init__ 
call so it's available in __init__.

--8<--------------------------------------------------------
from ref435 import Enum
from flags import IntET

class NIE1( IntET, Enum ):
     x =  1
     y =  2
     z =  4
     def __new__(cls, value):
         member = IntET.__new__(cls, 'temp', value)
         member._value = value
         return member
     def __init__(self, value):
         self._etname = self._name

print( repr( NIE1.x.value ))
print( repr( NIE1.x + NIE1.y ))
print( repr( NIE1.x + ~ NIE1.y))
print( repr( NIE1.x + ~ 2 ))
print( repr( NIE1.z * 3 ))


print( repr( NIE1( 1 ) + NIE1(2)))
print( repr( NIE1( IntET('NIE1.x', 1 )) + NIE1(2)))
--8<--------------------------------------------------------

and my results:

1
IntET('(x + y)', 3)
IntET('(x + ~y)', -2)
IntET('(x + -3)', -2)
IntET('(z * 3)', 12)
IntET('(x + y)', 3)
IntET('(x + y)', 3)


Oh, and if you really wanted the 'NEI' in the _etname, change the name assignment:

     self._etname = 'NIE.' + self._name

--
~Ethan~


More information about the Python-Dev mailing list