On Mon, Nov 08, 2021 at 01:43:03PM -0800, Ethan Furman wrote:
When is an empty container contained by a non-empty container? [...] SomeFlag.nothing in SomeFlag.something <-- ???
I don't think that consistency with other containers is particularly relevant here. More useful is consistency with other flag objects. What's SomeFlag? I presume it is some sort of Enum, or bitset. Presumably SomeFlag.nothing is equivalent to a bitset of all zeroes. (If it means something else, then I have no clue what to suggest.) You might have: something = 0b11010 0 in something # ??? 1 in something # False 2 in something # True 4 in something # False 8 in something # True 16 in something # True 32 in something # False So much is obvious. But what about `3 in something`? If that is interpreted as an *all* operation, you get: 3 in something --> all(i in something for i in (1, 2)) # False but if it is an *any* operation: 3 in something --> any(i in something for i in (1, 2)) # True I don't mean to imply that you must actually use all/any in your implementation. I mean only that it is conceptually equivalent to ANDing each of the flags (all) versus ORing the flags (any). *If* that is how you interpret your containment tests, that implies a natural interpretation for `nothing in something`. The vacuous truth of all is True, and of any is False: 0 in something --> all(i in something for i in ()) # True 0 in something --> any(i in something for i in ()) # False Vacuous truth is not the only possible interpretation. If you have some other obvious and natural interpretation of `0 in something` then you probably wouldn't be asking here, but if you did, you could follow that interpretation. With a good reason to violate the vacuous truth rules, it would only be a *little* surprising. -- Steve