<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#330033" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">On 4/4/2018 11:32 AM, Ethan Furman
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:5AC51A42.8080600@stoneleaf.us">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 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 False
      both in cases where the in-question object was an Enum of a
      different class (a Fruit in a Color, for example) and 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, 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 member of any
      kind -- it simply is not possible for that object to ever be in an
      Enum, and is surely a bug.
      <br>
      <br>
      For question 1B (mixed Enum):  if 1A is TypeError, then 1B should
      also be TypeError at least for non-mixin in-question types (so
      checking for 1 in StrEnum would be a TypeError), but I'm torn
      between TypeError and True/False for cases where the in-question
      type matches the mixin type ('apple' in StrEnum)....  On the one
      hand, even though an Enum member might be equal to some other
      type, that other type will not have the Enum attributes, etc, and
      a True answer would lead one to believe you could access `.name`
      and `.value`, etc., while a False answer would lead one to believe
      there was no match even though equality tests pass; on the other
      hand, how strong is the "container" aspect of a mixed Enum?  How
      often is the test `'apple' in Fruit` meant to discover if you have
      a Fruit member vs whether you have something that could be a Fruit
      member?  Also, how important is it to be consistent with IntFlag,
      which I definitely think should return True/False for int checks?
      <br>
      <br>
      For question 2A (pure Flag):  I'm comfortable sticking with a
      TypeError (assuming we switch to TypeError for 1A).
      <br>
      <br>
      For question 2B (int Flag):  I think a TypeError if the
      in-question object is not an int is appropriate (assuming
      TypeError for 1A and 2A), but if it is an int, True/False seems
      the better path.  My reasoning being that Flag and IntFlag are
      more similar to sets than lists, and IntFlag is specifically meant
      to work with ints, and a test of `2 in some_int_flags` is more
      concerned with a flag being set than with .name or .value
      attributes that may or may not exist on the in-question object.
      <br>
      <br>
      Any and all thoughts appreciated.<br>
    </blockquote>
    <br>
    I think the "in" test should raise TypeError if tested against
    _anything_ that is not an Enum member.<br>
    <br>
    Why? I see a parallel between Enum and mappings.<br>
    <br>
    x = {'test':True, 'live':False}<br>
    <br>
    So it is True that  'test' in x   and  'live' in x  and False that
    True in x and False in x.<br>
    <br>
    It is False that  'foo' in x  and  3 in x<br>
    <br>
    It is TypeError that [4,5,6] in x, or {'foo': 'bar'} in x.<br>
    <br>
    Note that it is False that (4,5,6) in x  which is a little
    surprising given the above two, but not when you realize the
    differences between this and the above two.<br>
    <br>
    So with mappings, you can have any hashable type as a key: with
    Enum, you can only have Enum members as keys.<br>
    <br>
    So I have no idea why you would want to return False, rather than
    TypeError, other than (1) the distinction probably doesn't matter to
    most people (2) backward compatibility.<br>
    <br>
    I would find   2 in some_int_flags  being True surprising.<br>
  </body>
</html>