Skip to content

Default enum.FlagBoundary should be KEEP? #93250

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

Closed
philthompson10 opened this issue May 26, 2022 · 6 comments
Closed

Default enum.FlagBoundary should be KEEP? #93250

philthompson10 opened this issue May 26, 2022 · 6 comments
Assignees
Labels
3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@philthompson10
Copy link

The FlagBoundary added to enums in Python v3.11 has defaults that break compatibility with previous versions. Shouldn't the default initially be KEEP, with a deprecation warning that it will be changed in a future version?

@philthompson10 philthompson10 added the type-bug An unexpected behavior, bug, or error label May 26, 2022
@AlexWaygood AlexWaygood added 3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir labels May 26, 2022
@The-Compiler
Copy link
Contributor

The-Compiler commented May 26, 2022

For some context: Python 3.11 and mixing of enum.IntFlag.

Reproducer:

import enum
A = enum.IntFlag("A", {"x": 1})
B = enum.IntFlag("B", {"y": 2})
val = A.x | B.y
print(val, type(val))
$ python3.10 -c 'import enum; A = enum.IntFlag("A", {"x": 1}); B = enum.IntFlag("B", {"y": 2}); val = A.x | B.y; print(val, type(val))'
A.B.y|x <enum 'A'>

but

$ python3.11 -c '...'
3 <class 'int'>

Relevant commit: 7aaeb2a ("bpo-38250: [Enum] single-bit flags are canonical (GH-24215)").

@ethanfurman
Copy link
Member

Are you concerned that the repr() has changed, or that the result is no longer of type flag?

@philthompson10
Copy link
Author

The change in type is the problem.

@ethanfurman
Copy link
Member

Changing the default to KEEP make sense.

Out of curiosity, and ignoring backwards compatibility, do you think the default for an IntFlag should be KEEP or EJECT?

@philthompson10
Copy link
Author

I don't feel comfortable with the type being different depending on the values provided, so I don't like EJECT as a default as the behaviour might be too surprising.

My use case is atypical. I am wrapping the enums of a C++ library and can't guarantee that the wrappers know about all the possible values that the library might provide. KEEP solves this problem. I have the same problem with Enum and IntEnum and have effectively implemented KEEP for those by providing them with an appropriate implementation of _missing_.

Note that my original concern was about the lack of the usual deprecation cycle for a change in behaviour rather than the change itself.

ethanfurman added a commit that referenced this issue May 27, 2022
…ibility (GH-93302)

In previous versions of Python if an IntEnum member was combined with another integer type value using a bit-wise operation, the resulting value would still be the IntEnum type.  This change restores that behavior.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 27, 2022
…compatibility (pythonGH-93302)

In previous versions of Python if an IntEnum member was combined with another integer type value using a bit-wise operation, the resulting value would still be the IntEnum type.  This change restores that behavior.
(cherry picked from commit 70cfe56)

Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
ethanfurman added a commit that referenced this issue May 27, 2022
…ibility (GH-93302) (GH-93304)

In previous versions of Python if an IntEnum member was combined with another integer type value using a bit-wise operation, the resulting value would still be the IntEnum type.  This change restores that behavior.
(cherry picked from commit 70cfe56)

Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
@ethanfurman
Copy link
Member

KEEP restored as the default, and likely to stay that way -- an early design decision was to persist the flag type for bit-wise operations. The exact flag type and behavior will depend on the left-most operand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants