fix(output): render Enum members as str in JSON serializer#9594
Merged
Conversation
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Member
Author
Contributor
|
@kirangadhave I have started the AI code review. It will take a few minutes to complete. |
Contributor
There was a problem hiding this comment.
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
Contributor
There was a problem hiding this comment.
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
mscolnick
approved these changes
May 19, 2026
|
🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.7-dev47 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Plain
enum.Enummembers displayed inmo.ui.tableor 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 stdlibjson.dumps. stdlib json has no nativeEnumsupport, so members reached the generic__dict__fallback inenc_hookand leaked their internals. The msgspec-nativeencode_json_strpath was unaffected because msgspec encodesEnumnatively (as.value).This adds an explicit
enum.Enumbranch inenc_hookahead of the__dict__/__slots__fallbacks that returnsstr(obj)(e.g."TestEnum.ONE").IntEnumandStrEnumstill match theirint/strisinstance branches first, so the existing test (encode_json_str(Color.RED) == "1") is preserved.Fixes #9576
Test plan
make py-checkpytest tests/_plugins/core/test_json_encoder.py -k enum(3 passed, including newtest_enum_via_sanitize_json_bigint)mo.ui.tableandpd.DataFrameviews showTestEnum.ONE/TestEnum.TWOin the Enum column