Enumeration idioms: Values from different enumerations

Ben Finney bignose+hates-spam at benfinney.id.au
Fri Dec 16 07:22:07 EST 2005


Antoon Pardon <apardon at forel.vub.ac.be> writes:
> Ben Finney wrote:
>> The 'enum' package in Cheeseshop [defines enumerations as]
>> sequences (of unique arbitrary values), that can be iterated and
>> tested for membership.
>
> Sure but we do have this:
>
>>>> from enum import Enum
>>>> day = Enum('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun')
>>>> col = Enum('red', 'green', 'blue')
>>>> lst= [day.mon, col.red]
>>>> col.blue in lst
> [...]
> enum.EnumValueCompareError: Not values from the same enumeration:

Yes, that looks like a case in favour of allowing at least equal-value
and not-equal-value comparisons.

>> The problem with "is the same value" as an explanation for '==' is
>> that it doesn't help in cases such as::
>>
>>     >>> ShirtSize = Enum('small', 'medium', 'large')
>>     >>> AppleSize = Enum('small', 'large')
>>
>> What should be the result of this comparison::
>>
>>     >>> ShirtSize.small == AppleSize.small
>>
>> Are they "the same value"? They're both "small" (and they both coerce
>> to the same string value, and in this case the same integer value).
>>
>> If not, is 'False' the right way to indicate that?
>
> I would agree 'False' is the right answer here.

Antoon Pardon wrote:
> Ben Finney wrote:
> > Would it be better if every Enum instance had its own unique
> > subclass of EnumValue, that was used to instantiate values for
> > that enumeration?
>
> If you decide on keeping the current behaviour when comparing
> values of different enumerations, I would definitely answer
> yes.

If values from different enums were to be compared for equality (and
not raise an exception), would it still be good to have those values
be of different types?

> This is a difficult question, because AFAIU python doesn't have
> clear guidelines for [comparisons between differing types]. I also
> have the impression that comparisons are used for two different
> reasons.

> The first is compare things in a mathematical kind of way in which
> how things are compared is important.

> The second is more an ordering mechanisme. Whether a string is
> greater than an int or vice versa, is not imporant what is important
> is that this order is consistent and can be used in binary searches,
> trees and other structures to organise data.

> Now python has only one collection of compare operators which can
> cause conflicts. For instance, one could impose an order on sets to
> use for such structure but that goes against the normal order on
> sets which is based on subsets.

> The only advise I have here is look at PEP 3000 that states:

> Comparisons other than == and != between disparate types will raise
> an exception unless explicitly supported by the type.

> Which seem to imply that == and != should not raise an exception but
> >, >=, <, <= should.

This seems like a good guide for a policy on enumerations.

How about this proposal:

Enumerations (instances of Enum) contain a fixed sequence of unique,
arbitrary values. The values within an enumeration are instances of a
type (subclass of EnumValue), unique to that enumeration.

Values from an enumeration can be compared for equality (__eq__,
__ne__) with any other value, and will only return True for the same
value from the same enumeration, otherwise False. Other comparison
operations can be performed only with values from the same
enumeration, otherwise an exception (EnumValueCompareError, subclass
of ValueError) is raised.

This might result in the following simplistic implementation::

    class EnumValue(object):
        # ...

        def __eq__(self, other):
            result = False
            if self is other:
                result = True
            return result

        def __cmp__(self, other):
            if isinstance(other, EnumValue):
                if is_same_enumeration(self, other):
                    result = cmp(self.index, other.index)
            else:
                raise EnumValueCompareError(self, other)
            return result

This gives meaning to the "equal value" comparisons, but ensures that
other comparisons are errors.

Comments so far?

-- 
 \      "I like to fill my bathtub up with water, then turn the shower |
  `\    on and pretend I'm in a submarine that's been hit."  -- Steven |
_o__)                                                           Wright |
Ben Finney



More information about the Python-list mailing list