-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enum.Flag.__contains__
changed behavior since python 3.12
#131045
Comments
1 | 2 becomes 3 and I think your surprise comes from the fact that a new member is automatically created. I think you can avoid this starting from 3.12 by specifying the boundary (namely a new member is not automatically created). I haven't checked but this should also have been documented somehow maybe indirectly. I believe that the reason is because the result of the OR of two enum flag members should remain an enum flag member by default (3.12+) and thus we create that additional member on the fly. With a different boundary the result would be a pure int and not an enum member. To check if this diagnosis is correct, print the type of the I can check on Wednesday as I'm unavailable until then (and I'm only answering from memory) |
This behaviour is documented for
Perhaps we should mention this in |
The intent is that One solution is to have |
…pythonGH-131053) Check would fail if value would create a pseudo-member, but that member had not yet been created. We now attempt to create a pseudo-member for a passed-in value first. (cherry picked from commit 17d06ae) Co-authored-by: Ethan Furman <ethan@stoneleaf.us> Co-authored-by: Tomas R. <tomas.roun8@gmail.com>
…31053) Check would fail if value would create a pseudo-member, but that member had not yet been created. We now attempt to create a pseudo-member for a passed-in value first. Co-authored-by: Tomas R. <tomas.roun8@gmail.com>
…pythonGH-131053) Check would fail if value would create a pseudo-member, but that member had not yet been created. We now attempt to create a pseudo-member for a passed-in value first. Co-authored-by: Tomas R. <tomas.roun8@gmail.com>
Bug report
Bug description:
I noticed some strange behavior with
enum.Flag
an the__contains__
method in Python 3.12/3.13, as shown in the following examples.Problem 1: Behavior changes at runtime
In the following code snippet the first print statement returns
False
, which is expected, since3
is not a member ofWeekday
. However, the second print statement returnsTrue
, which is unexpected, since3
is still not a member ofWeekday
.Problem 2: Behavior is not comparable to Python 3.11
Since Python 3.12 the behavior of
Enum.__contains__
has changed, so that it is possible to compare not only with an enum-member, but also with non-enum-members (see here or here). So with Python 3.11 the code above will raise anTypeError: unsupported operand type(s) for 'in': 'int' and 'EnumType'
. There you have to change the code to the following. But this in turn always produces unexpected behavior in Python 3.12/3.13.Conclusion
I would have expected that in all cases the result is
False
, but since Python 3.12 it gets very strange...CPython versions tested on:
3.12, 3.13
Operating systems tested on:
Windows
Linked PRs
The text was updated successfully, but these errors were encountered: