[Python-Dev] Enum, Flag, __contains__, and False vs TypeError
Ethan Furman
ethan at stoneleaf.us
Wed Apr 4 16:25:42 EDT 2018
On 04/04/2018 12:40 PM, Barry Warsaw wrote:
> On Apr 4, 2018, at 11:32, Ethan Furman wrote:
>> (A) A standard Enum class is a container of Enum members. It cannot hold anything else...
>>
>> (B) The waters get even more muddied when Fruit has a str mixin, so `Fruit.APPLE == 'apple' is True`...
>
> Are you proposing to change current behavior, and if so, what’s your deprecation plan?
The first problem is to determine what the correct behavior should be -- if that turns out to be different than what is
we can then decide the time frame for changing it. ;)
> I’m not sure I feel that the purity is important enough to change how it
> currently works, especially since you’ll have to be prepared to catch
> exceptions rather than just handle the boolean value.
It's not so much about purity as about bugs not passing silently. But whether or not it's a bug depends on how
"containerish" an Enum class is (or is perceived to be).
> OTOH, since most of my
> use cases are comparisons against explicit enum values, I’m not sure how often
> people write code to check for enum values contained in the Enum (I do it in
> one or two places where I’m deserializing the actual value object, e.g. from a
> pickle).
I write a bunch of cli scripts for work, so I'm often comparing a string value with an Enum value. As often as not, I
don't need the member itself, just to know that the string I have can be converted to a valid Enum -- `if "quick" in
Method`, for example -- but just converting to an Enum is undoubtedly the better course of action .
> (FWIW, I encourage individual comparisons use `is` rather than `==`.)
Which is great for pure Enums, not so much for mixed.
>> Question 2:
>> ----------
>>
>> (A) The new Flag type allows `in` tests on the members themselves; so, for example:
>>
>> --> SomeFlag.ONE in SomeFlag.One|SomeFlag.TWO
>> True
>>
>> The question, of course, is what to do when a non-Flag member is tested for:
>>
>> --> 'apple' in SomeFlag.ONE
>> # False or TypeError?
>>
>> --> 2 in SomeFlag.TWO
>> # True or TypeError?
>>
>> (B) And, of course, the same muddier question arises with IntFlag, where SomeFlag.TWO == 2 is True.
>
> Well, now I’m confused:
>
> Python 3.7.0b2+ (heads/3.7:f328caf4ca, Mar 26 2018, 19:57:33)
> [Clang 9.0.0 (clang-900.0.39.2)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
> --> from enum import IntFlag
> --> class Flag(IntFlag):
> ... a = 1
> ... b = 2
> ... c = 4
> ... d = 8
> ...
> --> 'foo' in (Flag.a|Flag.b)
> True
Already being tracked at https://bugs.python.org/issue33217, which is what got me thinking about this whole issue. True
is obviously wrong, but should the correct answer be False, or TypeError?
--
~Ethan~
More information about the Python-Dev
mailing list