[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