Skip to content

fix(output): render Enum members as str in JSON serializer#9594

Merged
kirangadhave merged 1 commit into
mainfrom
kg/enum-display-fix
May 19, 2026
Merged

fix(output): render Enum members as str in JSON serializer#9594
kirangadhave merged 1 commit into
mainfrom
kg/enum-display-fix

Conversation

@kirangadhave
Copy link
Copy Markdown
Member

@kirangadhave kirangadhave commented May 18, 2026

Summary

Plain enum.Enum members displayed in mo.ui.table or as a pandas DataFrame rendered their __dict__ internals (_value_, _name_, __objclass__, _sort_order_) instead of a readable label.

The table/DataFrame path serializes cells through sanitize_json_bigint, which uses stdlib json.dumps. stdlib json has no native Enum support, so members reached the generic __dict__ fallback in enc_hook and leaked their internals. The msgspec-native encode_json_str path was unaffected because msgspec encodes Enum natively (as .value).

This adds an explicit enum.Enum branch in enc_hook ahead of the __dict__/__slots__ fallbacks that returns str(obj) (e.g. "TestEnum.ONE"). IntEnum and StrEnum still match their int/str isinstance branches first, so the existing test (encode_json_str(Color.RED) == "1") is preserved.

Fixes #9576

Test plan

  • make py-check
  • pytest tests/_plugins/core/test_json_encoder.py -k enum (3 passed, including new test_enum_via_sanitize_json_bigint)
  • Manual repro from the bug report — mo.ui.table and pd.DataFrame views show TestEnum.ONE / TestEnum.TWO in the Enum column

Plain `Enum` members hit the generic `__dict__` fallback in `enc_hook`
and serialized their internals. Add an explicit branch that returns
`str(obj)` so tables and DataFrame views show readable labels.
`IntEnum`/`StrEnum` keep their int/str isinstance fast-path.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment May 18, 2026 11:58pm

Request Review

@kirangadhave
Copy link
Copy Markdown
Member Author

@cubic-dev-ai

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 18, 2026

@cubic-dev-ai

@kirangadhave I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Architecture diagram
sequenceDiagram
    participant UI as mo.ui.table / DataFrame
    participant Sanitize as sanitize_json_bigint()
    participant JSONLib as stdlib json.dumps
    participant EncHook as enc_hook()
    participant EnumMember as Enum Member (e.g. TestEnum.ONE)
    participant Fallback as __dict__ / __slots__ fallback

    Note over UI,Sanitize: Table serialization path
    UI->>Sanitize: serialize cell values
    Sanitize->>JSONLib: json.dumps() with enc_hook
    JSONLib->>EncHook: call enc_hook(obj)
    EncHook->>EnumMember: isinstance(obj, enum.Enum)?
    alt Is Enum
        EncHook-->>JSONLib: return str(obj) (e.g. "TestEnum.ONE")
    else Not Enum
        EncHook->>Fallback: check __dict__ / __slots__
        Fallback-->>JSONLib: return dict/list
    end
    JSONLib-->>Sanitize: JSON string
    Sanitize-->>UI: rendered cell values

    Note over UI,Sanitize: msgspec path (unaffected)
    alt IntEnum member (e.g. Color.RED)
        EncHook->>EnumMember: isinstance(obj, int)?
        EncHook-->>JSONLib: return obj.value (e.g. 1)
    else StrEnum member
        EncHook->>EnumMember: isinstance(obj, str)?
        EncHook-->>JSONLib: return obj.value
    end
Loading

Re-trigger cubic

@kirangadhave kirangadhave added the bug Something isn't working label May 18, 2026
@kirangadhave kirangadhave marked this pull request as ready for review May 18, 2026 23:59
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Architecture diagram
sequenceDiagram
    participant UI as mo.ui.table / DataFrame
    participant Sanitize as sanitize_json_bigint()
    participant JSONLib as stdlib json.dumps
    participant EncHook as enc_hook()
    participant EnumMember as Enum Member (e.g. TestEnum.ONE)
    participant Fallback as __dict__ / __slots__ fallback

    Note over UI,Sanitize: Table serialization path
    UI->>Sanitize: serialize cell values
    Sanitize->>JSONLib: json.dumps() with enc_hook
    JSONLib->>EncHook: call enc_hook(obj)
    EncHook->>EnumMember: isinstance(obj, enum.Enum)?
    alt Is Enum
        EncHook-->>JSONLib: return str(obj) (e.g. "TestEnum.ONE")
    else Not Enum
        EncHook->>Fallback: check __dict__ / __slots__
        Fallback-->>JSONLib: return dict/list
    end
    JSONLib-->>Sanitize: JSON string
    Sanitize-->>UI: rendered cell values

    Note over UI,Sanitize: msgspec path (unaffected)
    alt IntEnum member (e.g. Color.RED)
        EncHook->>EnumMember: isinstance(obj, int)?
        EncHook-->>JSONLib: return obj.value (e.g. 1)
    else StrEnum member
        EncHook->>EnumMember: isinstance(obj, str)?
        EncHook-->>JSONLib: return obj.value
    end
Loading

Re-trigger cubic

@kirangadhave kirangadhave merged commit 9b1f94a into main May 19, 2026
63 of 70 checks passed
@kirangadhave kirangadhave deleted the kg/enum-display-fix branch May 19, 2026 02:17
@github-actions
Copy link
Copy Markdown

🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.7-dev47

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enums in table and pd.DataFrame does not display properly

2 participants