-
-
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 <[email protected]> Co-authored-by: Tomas R. <[email protected]>
…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. <[email protected]>
…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. <[email protected]>
GH-131053) (#131167) gh-131045: [Enum] fix flag containment checks when using values (GH-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 <[email protected]> Co-authored-by: Tomas R. <[email protected]>
@ethanfurman What do you want to do with the backports? 3.12 is nearing its last bug fix so I wonder whether you are willing to review my PR (which had conflicts that I resolved but I'm not sure it's entirely correct for you) |
Thanks for taking care of that; my PC has been having issues this last week. |
GH-131053) (#131232) * gh-131045: [Enum] fix flag containment checks when using values (GH-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: Ethan Furman <[email protected]> Co-authored-by: Tomas R. <[email protected]>
Thank you for the report and for the fix! |
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: