<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, 4 Apr 2018 at 11:30 Ethan Furman <<a href="mailto:ethan@stoneleaf.us">ethan@stoneleaf.us</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">API question.<br>
<br>
Background:<br>
----------<br>
<br>
When doing checks such as<br>
<br>
--> 3 in [4, 5, 6]<br>
--> 'test' in {'test':True, 'live':False}<br>
<br>
the result is True or False.<br>
<br>
When doing checks such as<br>
<br>
--> 3 in 'hello world'<br>
--> [4, 5, 6] in {'test':True, 'live':False}<br>
<br>
the result is a TypeError.<br>
<br>
The general rule seems to be that if it is impossible for the in-question object to be in the container object then a<br>
TypeError is raised, otherwise True or False is returned.<br>
<br>
<br>
Question 1:<br>
----------<br>
<br>
(A) A standard Enum class is a container of Enum members.  It cannot hold anything else.  However, it has been returning<br>
False both in cases where the in-question object was an Enum of a different class (a Fruit in a Color, for example) and<br>
when the in-question object was not even an Enum ('apple' in Fruit, for example).<br>
<br>
(B) The waters get even more muddied when Fruit has a str mixin, so `Fruit.APPLE == 'apple' is True` -- in that case,<br>
should `'orange' in Fruit` return True, False, or raise TypeError?<br>
<br>
<br>
Question 2:<br>
----------<br>
<br>
(A) The new Flag type allows `in` tests on the members themselves; so, for example:<br>
<br>
--> SomeFlag.ONE in SomeFlag.One|SomeFlag.TWO<br>
True<br>
<br>
The question, of course, is what to do when a non-Flag member is tested for:<br>
<br>
--> 'apple' in SomeFlag.ONE<br>
# False or TypeError?<br>
<br>
--> 2 in SomeFlag.TWO<br>
# True or TypeError?<br>
<br>
(B) And, of course, the same muddier question arises with IntFlag, where SomeFlag.TWO == 2 is True.<br>
<br>
<br>
My thoughts:<br>
-----------<br>
<br>
For question 1A (pure Enum):  I'm thinking a TypeError should be raised when the in-question object is not an Enum<br>
member of any kind -- it simply is not possible for that object to ever be in an Enum, and is surely a bug.<br></blockquote><div><br></div><div>Yes, although it sounds like it already does the other thing, so do you want to start raising TypeError immediately or go for a deprecation period?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
For question 1B (mixed Enum):  if 1A is TypeError, then 1B should also be TypeError at least for non-mixin in-question<br>
types (so checking for 1 in StrEnum would be a TypeError), but I'm torn between TypeError and True/False for cases where<br>
the in-question type matches the mixin type ('apple' in StrEnum)....  On the one hand, even though an Enum member might<br>
be equal to some other type, that other type will not have the Enum attributes, etc, and a True answer would lead one to<br>
believe you could access `.name` and `.value`, etc., while a False answer would lead one to believe there was no match<br>
even though equality tests pass; on the other hand, how strong is the "container" aspect of a mixed Enum?  How often is<br>
the test `'apple' in Fruit` meant to discover if you have a Fruit member vs whether you have something that could be a<br>
Fruit member?  Also, how important is it to be consistent with IntFlag, which I definitely think should return<br>
True/False for int checks?<br></blockquote><div><br></div><div>I think this is a design question as to how interchangeable you want these kind of enums to be, and I personally have no opinion as I have never needed to use them.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
For question 2A (pure Flag):  I'm comfortable sticking with a TypeError (assuming we switch to TypeError for 1A).<br></blockquote><div><br></div><div>Makes sense.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
For question 2B (int Flag):  I think a TypeError if the in-question object is not an int is appropriate (assuming<br>
TypeError for 1A and 2A), but if it is an int, True/False seems the better path.  My reasoning being that Flag and<br>
IntFlag are more similar to sets than lists, and IntFlag is specifically meant to work with ints, and a test of `2 in<br>
some_int_flags` is more concerned with a flag being set than with .name or .value attributes that may or may not exist<br>
on the in-question object.<br></blockquote><div><br></div><div>Same as above; no experience so no opinion.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Any and all thoughts appreciated.<br>
<br>
--<br>
~Ethan~<br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/brett%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/brett%40python.org</a><br>
</blockquote></div></div>