Skip to content

Cross-module enum class imports fail when classes are split across generated modulesΒ #236

@timosachsenberg

Description

@timosachsenberg

Problem Description

When using cdef enum class with wrap-attach: directive, autowrap splits the generated code across multiple _pyopenms_N.pyx files for parallel compilation. However, when an enum class is defined in one module (e.g., _pyopenms_2.pyx) but used as a parameter type in a class method that ends up in a different module (e.g., _pyopenms_5.pyx), the necessary cross-module import is missing.

Example

In IonSource.pxd:

cdef extern from "<OpenMS/METADATA/IonSource.h>" namespace "OpenMS":
    cdef cppclass IonSource(MetaInfoInterface):
        void setPolarity(Polarity polarity) except + nogil

cdef extern from "<OpenMS/METADATA/IonSource.h>" namespace "OpenMS::IonSource":
    cdef enum class Polarity "OpenMS::IonSource::Polarity":
        # wrap-attach:
        #    IonSource
        POLNULL, POSITIVE, NEGATIVE, SIZE_OF_POLARITY

Generated Code Issue

  • _pyopenms_2.pyx contains: class _PyPolarity(_PyEnum): ...
  • _pyopenms_5.pyx contains: assert isinstance(in_0, _PyPolarity), 'arg in_0 wrong type'

But _pyopenms_5.pyx never imports _PyPolarity from _pyopenms_2, causing:

pyopenms/_pyopenms_5.pyx:5313:32: undeclared name not builtin: _PyPolarity

Affected Cases

This affects any enum class used as a function parameter when autowrap places the enum definition and the function in different output modules:

  1. SpectrumType (SpectrumSettings) - _PySpectrumType defined in _pyopenms_3, used in _pyopenms_4
  2. Polarity (IonSource) - _PyPolarity defined in _pyopenms_2, used in _pyopenms_5
  3. MODELTYPE (MZTrafoModel) - _PyMODELTYPE defined in _pyopenms_2, used in _pyopenms_7

Related

This appears related to Cython issue #5609 regarding mixed imports/cimports of enums across modules.

Expected Behavior

Autowrap should either:

  1. Generate proper cross-module imports for enum classes used as parameters
  2. Keep enum class definitions in the same module as the classes they're attached to
  3. Generate a shared module for all enum classes that other modules import from

Environment

  • autowrap version: (latest from pip)
  • Cython version: 0.29.x / 3.x
  • Python: 3.10
  • OpenMS: develop branch (PR converting plain enums to enum class)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions