Skip to content

3.12.0b4 enum.IntFlag NoneType object is not iterable #106928

Description

@cdce8p

Bug report

import enum

class bitmap(enum.IntFlag):
    pass

print(bitmap.from_bytes(b'\x00', 'little'))

3.11

bitmap(0)

3.12.0b4

Traceback (most recent call last):
  File "/.../cpython/test.py", line 6, in <module>
    print(bitmap.from_bytes(b'\x00', 'little'))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../cpython/Lib/enum.py", line 742, in __call__
    return cls._create_(
           ^^^^^^^^^^^^^
  File "/.../cpython/Lib/enum.py", line 870, in _create_
    for item in names:
TypeError: 'NoneType' object is not iterable

I bisected the issue to #99500.
/CC: @ethanfurman

Your environment

  • CPython versions tested on: 3.12.0b4
  • Operating system and architecture: macOS ARM64

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Jul 20, 2023
  2. self-assigned this
    on Jul 20, 2023
  3. ethanfurman commented on Jul 20, 2023

    @ethanfurman
    Member

    Thank you for the report!

    What is your use-case for this behavior? Typically, an enum with no members is meant to be subclassed.

  4. added
    stdlibStandard Library Python modules in the Lib/ directory
    3.12only security fixes
    3.13only security fixes
    on Jul 20, 2023
  5. cdce8p commented on Jul 20, 2023

    @cdce8p
    ContributorAuthor

    What is your use-case for this behavior? Typically, an enum with no members is meant to be subclassed.

    Tbh I stumbled upon this while testing a third party library: https://github.com/zigpy/zigpy
    As best as I can tell, they do also subclass it, but bitmap.from_bytes in that case is used in a deserialization routine from a binary struct.

    I could post a longer example, just not sure it's all that useful, that's why I condensed it initially.

  6. ethanfurman commented on Jul 21, 2023

    @ethanfurman
    Member

    Please open an issue with zigpy and reference this one. They should be able to confirm if this is a problem in practice.

  7. puddly commented on Jul 26, 2023

    @puddly

    While this new 3.12 behavior is backwards-incompatible with Python 3.11, we've resolved this problem by avoiding the functional API by replacing the enum metaclass (zigpy/zigpy#1236):

    import enum
    
    
    class AlwaysCreateEnumType(enum.EnumMeta):
        """Enum metaclass that skips the functional creation API."""
    
        def __call__(cls, value, names=None, *values) -> type[enum.Enum]:  # type: ignore
            return cls.__new__(cls, value)  # type: ignore
    
    
    class bitmap8(
        int,
        enum.ReprEnum,
        enum.Flag,
        boundary=enum.KEEP,
        metaclass=AlwaysCreateEnumType,
    ):
        pass
    
    bitmap8(0)  # works with 3.11 and 3.12

    You can consider this issue resolved if no other projects rely on using the enum classes this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

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

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions