So, thanks everyone for helping me understand the metaclass issues, and helping fix my code and the reference implementation, so that I got a working workaround for enumerations.

Twiddling some more.... newly using hg and bitbucket... learned a lot today... at <https://bitbucket.org/v_python/ref435a/src>

Premise: For API parameters that are bitfields, it would be nice to have an Enum-type class that tracks the calculations done with the named values to create bit masks.

Currently available: Enum (or IntEnum) that can group the collection of named bit-field values into values of a single and unique type, but loses the names during calculations.

Just written: a class IntET (for "int expression tracker" which has an expression name as well as a value. As a side effect, this could be used to track effective calculations of integers for debugging, because that is the general mechanism needed to track combined flag values, also for debug reporting.

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.

It is cumbersome to specify redundant names for the enumeration members and the underlying IntET separately, however.

Turns out that adding one line to ref435 (which I did in ref435a) will allow (nay, require) that base types for these modified Enums must have names, which must be supplied as the first parameter to their constructor. This also works around whatever problem "real" Enum has with using named items internally, as demonstrated by demo2.py (reproduced in part here):

class NIE( IntET, Enum ):
    x = 1
    y = 2
    z = 4

print( repr( NIE.x + NIE.y ))
IntET('(NIE.x + NIE.y)', 3)

So the questions are:
1) Is there a bug in ref435 Enum that makes demo1 report errors instead of those lines working? 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. 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? 4) Or is it simple enough and useful enough to somehow make it a feature of EnumMeta, enabled by a keyword parameter? Or one _could_ detect the existence of a __name__ property on the first base type, and key off of that, but that may sometimes be surprising (of course, that is what documentation is for: to explain away the surprises people get when they don't read it). 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.)

Probably some of these questions should be on stackoverflow or python ideas, but it is certainly an outgrowth of the Enum PEP, and personally, I'd hate to see flag APIs converted to Enum without the ability to track combinations of them... so I hope that justifies parts of this discussion continuing here. I'm happy to take pieces to other places, if so directed.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to