Issue33219
Created on 2018-04-03 20:38 by Dutcho, last changed 2022-04-11 14:58 by admin. This issue is now closed.
| Messages (7) | |||
|---|---|---|---|
| msg314893 - (view) | Author: (Dutcho) | Date: 2018-04-03 20:38 | |
While `enum.IntFlag.__and__` accepts an int arg `other` and converts it to `IntFlag` before masking, `enum.IntFlag.__contains__` handles an int arg `other` no different from a different type arg `other` (i.e. returns `True` in Python 3.6 due to issue 33217, but would raise `TypeError` after that's fixed): >>> import enum >>> ABC = enum.Flag('ABC', 'a, b, c') >>> ac = ABC.a | ABC.c >>> ABC.b in ac # works False >>> 2 in ac # should be the same; no exception due to issue 33217 True >>> ac & 3 # works, equivalent to ac & ABC(3) <ABC.a: 1> This is caused by a lack of specialized `IntFlag.__contains__`, so `Flag.__contains__` does the work. Can be fixed by adding a specialization, which (like in `IntFlag.__and__`) tests for `isinstance(other, (IntFlag, int))`. >>> def __contains__(self, other): ... if not isinstance(other, (self.__class__, int)): ... return TypeError ... return other & self == other # conversion of int to IntFlag implicitly handled by IntFlag.__and__ >>> IntFlag.__contains__ = __contains__ |
|||
| msg314897 - (view) | Author: Ethan Furman (ethan.furman) * ![]() |
Date: 2018-04-03 21:10 | |
issue33217 will not be "fixed" with a TypeError, but incorrect Falses are also bad. Rather than add __contains__ to IntFlag (and every other Flag mixin), I think the best answer is to adjust Flag.__contains__ a little bit more to check if `other` is of the same type as the mixin class, and if so see if it's one of the values. Thank you for being thorough and finding this problem as well. |
|||
| msg314912 - (view) | Author: Nitish (nitishch) * | Date: 2018-04-04 02:37 | |
@Ethan Furman how can Flag do that? IntFlag can deal with int values too. Would it be possible to deal with int values in this case in Flag.__contains__? |
|||
| msg314951 - (view) | Author: (Dutcho) | Date: 2018-04-04 21:03 | |
@Nitish
The easiest way would probably be to change __contains__ in Flag to:
def __contains__(self, other):
try:
return other & self == other # leave selection of _value_ attribute (if other is Flag) or conversion (if other is int mixin of IntFlag) to __and__
except TypeError:
return False
Although this would be somewhat convoluted (the generic delegation to __and__ isn't clear at first sight and therefore less maintainable) and may lead to confusing error messages
|
|||
| msg314959 - (view) | Author: Ethan Furman (ethan.furman) * ![]() |
Date: 2018-04-04 23:14 | |
Nitish, Flag can check if the current Flag class has a mixin, and if so if the object being checked for is of that same type. Dutcho, my apologies. Looks like I did not fully understand how __contains__ is supposed to work and a TypeError is completely appropriate. Looking into deprecation cycles now to get the change scheduled. |
|||
| msg314993 - (view) | Author: Ethan Furman (ethan.furman) * ![]() |
Date: 2018-04-05 16:32 | |
issue33217 is tracking member-containment checks; modifying this one to track class-containment checks. Given class Color(Enum): RED = 1 class Fruit(Enum): APPLE = 1 then --> Fruit.APPLE in Color False --> Fruit.APPLE in Fruit True --> 1 in Fruit TypeError The last is currently returning False instead of raising a TypeError. |
|||
| msg315233 - (view) | Author: Ethan Furman (ethan.furman) * ![]() |
Date: 2018-04-12 21:34 | |
This and issue33217 are similar enough I'm going to track it in issue33217. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:58:59 | admin | set | github: 77400 |
| 2018-04-12 21:34:06 | ethan.furman | set | status: open -> closed superseder: x in enum.Flag member is True when x is not a Flag messages: + msg315233 resolution: duplicate |
| 2018-04-05 16:32:04 | ethan.furman | set | versions:
+ Python 3.7 title: x in IntFlag() should test int x's inclusion in IntFlag -> x in IntFlag should test raise TypeError if x is not an IntFlag messages: + msg314993 type: enhancement -> behavior |
| 2018-04-04 23:14:49 | ethan.furman | set | messages: + msg314959 |
| 2018-04-04 21:03:56 | Dutcho | set | messages: + msg314951 |
| 2018-04-04 02:37:00 | nitishch | set | nosy:
+ nitishch messages: + msg314912 |
| 2018-04-03 21:10:50 | ethan.furman | set | keywords:
+ easy messages: + msg314897 |
| 2018-04-03 20:49:59 | ethan.furman | set | assignee: ethan.furman nosy:
+ barry, eli.bendersky, ethan.furman |
| 2018-04-03 20:38:20 | Dutcho | create | |
