On Mon, Nov 8, 2021 at 7:26 PM Ethan Furman <ethan@stoneleaf.us> wrote:
Let's use a concrete example:  `re.RegexFlag`

```
Help on function match in module re:

match(pattern, string, flags=0)
     Try to apply the pattern at the start of the string, returning
     a Match object, or None if no match was found.
```

In use we have:

     result = re.match('present', 'who has a presence here?', re.IGNORECASE|re.DOTALL)

Inside `re.match` we have `flags`, but we don't know if `flags` is nothing (0), a single flag (re.ASCII, maybe) or a
group of flags (such as in the example).  For me, the obvious way to check is with:

     if re.IGNORECASE in flags:  # could be re.I in 0, re.I in 2, re.I in 5, etc.
        ...

Yes.

Now, suppose for the sake of argument that there was a combination of flags that had its own code path, say

     weird_case = re.ASCII | re.LOCALE | re.MULTILINE

I can see that going two ways:

     weird_case in flags   # if other flags allowed

I would spell this as

    if flags & weird_case == weird_case:
 
(which BTW works too if `flags` and `weird_case` are sets!)

or

     weird_case is flags   # if no other flags allowed

this should be spelled using `==`, not using `is` (which is reserved for identity, but here we're comparing values). And again this works for sets too. (Just don't confuse set elements with subsets!)
 
The idiom that I'm shooting for is using `in` to check for flags:

- flag1 in flag1             True
- flag1 in (flag1 | flag2)   True
- flag3 in (flag1 | flag2)   True

Did you mean False for this last one?

- flag3 in flag1             False
- flag3 in flag4             False

When `flag` is a single flag bit and `flags` is an unknown combination of flag bits, you can conceivably make it so you can write this as `flag in flags`. But `in` doesn't work when sets are represented as bits in an integer (which is the analogy you're going for?)
 
and

- flag0 in any flag          False
- any flag in flag0          False

What is `any flag` here?
 
And, of course, if we want to know if the thing we have is exactly flag1:

     flag is flag1

will tell us.

Please use `==` here.
 
Does this make sense?

WHen thinking about sets of flag bits, do you actually visualize them as bits in an integer? That's how I always think of them. Suppose we have three flags, F1, F2 and F3. Let's write them in binary:

F1 = 0b001
F2 = 0b010
F3 = 0b100

Let's have a flags variable composed of F1 and F3:

flags = 0b101

F1 & flags is a bitwise AND of 0b001 and 0b101, which of course is 0b001 (and so on):

F1 & flags == 0b001 & 0b101 == 0b001
F2 & flags == 0b010 & 0b101 == 0b000
F3 & flags == 0b100 & 0b101 == 0b100

IF weird_case is F2 combined with F3, we get

weird_case == F2|F3 == 0b010|0b100 == 0b110

Etc., etc.

--
--Guido van Rossum (python.org/~guido)