Skip to content

Use IntEnum instead of Enum for enum class wrappers#222

Merged
timosachsenberg merged 1 commit intomasterfrom
fix-intenum-for-enum-class
Nov 29, 2025
Merged

Use IntEnum instead of Enum for enum class wrappers#222
timosachsenberg merged 1 commit intomasterfrom
fix-intenum-for-enum-class

Conversation

@timosachsenberg
Copy link
Collaborator

@timosachsenberg timosachsenberg commented Nov 29, 2025

Summary

  • Change generated Python enum wrappers to inherit from IntEnum instead of Enum
  • Fixes a bug where set parameters containing enum class values fail with "TypeError: an integer is required"

Problem

When using cdef enum class (C++ scoped enum) with set parameters, the generated Cython code would fail:

def setActivationMethods(self, set activation_methods):
    cdef int item0
    for item0 in activation_methods:  # FAILS: Enum objects can't be assigned to cdef int
        v0.insert(<_ActivationMethod> item0)

With plain Enum:

  • Enum members are NOT integers
  • int(MyEnum.A) throws TypeError
  • Only .value works to get the integer

Solution

Use IntEnum instead:

  • IntEnum members ARE integers (isinstance(val, int) is True)
  • Cython's cdef int can directly accept IntEnum values
  • Round-trip operations (get → set) work correctly
  • Backwards compatible with code expecting integers

Testing

Tested with pyOpenMS which uses cdef enum class ActivationMethod in Precursor.pxd. The test that was previously failing (testPrecursor) now passes.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • Updated enum representation in generated type stubs and C imports. The base class used for enum type handling has been modified to improve type consistency and representation for scoped enums across generated code artifacts.

✏️ Tip: You can customize this high-level summary in your review settings.

Change the generated Python enum wrappers to inherit from IntEnum
instead of Enum. This fixes a bug where set parameters containing
enum class values would fail with "TypeError: an integer is required"
when iterating.

The issue was that:
1. Generated code declares `cdef int item0` for iteration
2. But iterating over a set of Enum values yields Enum objects, not ints
3. Cython cannot assign an Enum object to `cdef int`

With IntEnum:
- Enum values ARE integers (isinstance(val, int) is True)
- Cython's `cdef int` can directly accept IntEnum values
- Round-trip operations (get → set) work correctly
- Backwards compatible with code expecting integers

Tested with pyOpenMS which uses `cdef enum class ActivationMethod`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 29, 2025

Walkthrough

The pull request modifies enum handling in code generation by changing the imported alias from Enum to IntEnum in generated Python stubs and Cython imports. This affects how scoped enums are represented in the generated output code.

Changes

Cohort / File(s) Change Summary
Enum Import Alias Update
autowrap/CodeGenerator.py
Changed the exported enum superclass alias in generated stubs and C imports from from enum import Enum as _PyEnum to from enum import IntEnum as _PyEnum, affecting type stub generation and Cython import configuration.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • Areas requiring attention:
    • Verify that the change from Enum to IntEnum is intentional and aligns with project requirements
    • Confirm that all generated code using _PyEnum as a base class functions correctly with IntEnum semantics (note: IntEnum has different behavior than Enum, as members are also integers)
    • Test that existing enum generation use cases continue to work as expected
    • Check for any type hints or documentation that may reference the old enum type

Poem

🐰 An enum hops from a general base,
To integers with greater grace,
IntEnum now takes the crown so bright,
Making scoped enums feel just right!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: replacing Enum with IntEnum for enum class wrappers in generated code.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-intenum-for-enum-class

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0501161 and e10a742.

📒 Files selected for processing (1)
  • autowrap/CodeGenerator.py (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: test (==3.2.0, 3.13)
  • GitHub Check: test (==3.2.0, 3.12)
  • GitHub Check: test (==3.2.0, 3.10)
  • GitHub Check: test (==3.1.0, 3.13)
  • GitHub Check: test (==3.2.0, 3.11)
  • GitHub Check: test (==3.1.0, 3.12)
  • GitHub Check: test (==3.1.0, 3.11)
  • GitHub Check: test (==3.1.0, 3.10)
🔇 Additional comments (1)
autowrap/CodeGenerator.py (1)

351-352: IntEnum change for scoped enums is correct and well-tested; one concern in the original review is invalid

The switch from Enum to IntEnum for _PyEnum is intentional and properly tested. Both import statements (line 351 in pyi generation and line 2043 in default Cython imports) correctly target scoped enums only—unscoped enums continue to use cdef class (verified in lines 447–476).

One point from the original review requires correction:

Python version / enum34 support is not a concern.
The project requires Python ≥3.9 (per pyproject.toml), and IntEnum has been in the stdlib since Python 3.4. No backport or version gating is needed.

The second concern about behavioral edge cases (truthiness, arithmetic) remains valid but theoretical. The existing test suite exercises enum type validation and cross-module usage but does not explicitly test the int-like behavior of IntEnum members. This is likely acceptable since:

  • The intended use is interop with C++ integer enums (cdef int fields).
  • Enum members as integers is the expected behavior for this pattern.

The change is correct and consistent.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant