Skip to content

Default enum.FlagBoundary should be KEEP? #93250

Description

@philthompson10

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?

Activity

  1. added
    3.11only security fixes
    3.12only security fixes
    stdlibStandard Library Python modules in the Lib/ directory
    on May 26, 2022
  2. The-Compiler commented on May 26, 2022

    @The-Compiler
    Contributor

    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)").

  3. ethanfurman commented on May 26, 2022

    @ethanfurman
    Member

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

  4. philthompson10 commented on May 26, 2022

    @philthompson10
    Author

    The change in type is the problem.

  5. ethanfurman commented on May 26, 2022

    @ethanfurman
    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?

  6. philthompson10 commented on May 27, 2022

    @philthompson10
    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.

  7. added a commit that references this issue on May 27, 2022
  8. added a commit that references this issue on May 27, 2022
  9. added a commit that references this issue on May 27, 2022
  10. ethanfurman commented on May 27, 2022

    @ethanfurman
    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

Metadata

Metadata

Assignees

Labels

3.11only security fixes3.12only security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions