Skip to content

Add support for Enum#33

Open
renan-r-santos wants to merge 2 commits into
drhagen:masterfrom
renan-r-santos:add-support-for-enums
Open

Add support for Enum#33
renan-r-santos wants to merge 2 commits into
drhagen:masterfrom
renan-r-santos:add-support-for-enums

Conversation

@renan-r-santos

@renan-r-santos renan-r-santos commented Dec 12, 2025

Copy link
Copy Markdown
Contributor

Fixes #5

I checked two other serialization libraries, msgspec and Pydantic, and they both serialize Enums to their values. I also think this is more appropriate for IntEnum, so decided to diverge from the original issue description. Let me know what you think.

@codecov-commenter

codecov-commenter commented Dec 12, 2025

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 97.46835% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.69%. Comparing base (da90724) to head (3abbb42).

Files with missing lines Patch % Lines
src/serialite/_implementations/_enum.py 96.92% 1 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #33      +/-   ##
==========================================
+ Coverage   92.43%   92.69%   +0.25%     
==========================================
  Files          34       35       +1     
  Lines        1468     1547      +79     
  Branches      219      231      +12     
==========================================
+ Hits         1357     1434      +77     
- Misses         49       50       +1     
- Partials       62       63       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@drhagen

drhagen commented Dec 12, 2025

Copy link
Copy Markdown
Owner

Thanks for this contribution. Let me think more about the right thing to do with regard to this:

serialize Enums to their values

My motivation for the original design is that this is the canonical use of enums:

from enum import Enum, auto

class Foo(Enum):
    a = auto()
    b = auto()

But serialize this and, I don't know if you get what you expect, but you certainly don't get something useful.

Your design also works on things like:

class Foo(Enum):
    a = {}
    b = {"a": 1}

But kind of accidentally. It does not work on things like:

class Status(Enum):
    success = Success("Job completed successfully")
    failure = Failure("Job failed")
    crashed = Failure("Server did not start")

It would not work on the planet example.

I always thought of the "value" of an enum as the Python payload. I find it strange that other tools treat the value as the "serialization representation". I guess this makes sense if you have a lot of enums whose serialized representations are not appropriate Python enum names (e.g. ACTIVE = "active" or ok = 200.

I had also envisioned this only working with @serializable or similar decorator. I had not considered just dispatching on all enums. I have to think about that some more too.

@renan-r-santos

Copy link
Copy Markdown
Contributor Author

I've been thinking more about this and came around to serializing by name by default rather than by value. It has better interoperability with other languages and serialization frameworks. Value-based serialization is still supported as an opt-in.

Regarding dispatching on all enums vs. requiring a decorator, I prefer dispatch. For the cases where you want different behavior (like by-value), field(serializer=...) is available.

@drhagen

drhagen commented Feb 27, 2026

Copy link
Copy Markdown
Owner

In typical use of Serialite, classes define themselves how they are serialized by default. Obviously, this cannot be done for builtin Python classes, so Serialite provides the dispatcher to define default serialization. But also, you can override the default serializer for anything by providing it to field(serializer=...).

By putting Enum in the dispatcher, this would be the first time in Serialite where you define a class, but get no control over how that class is serialized by default. So, I still feel like this should be defined on the class. I am on the fence as to whether or not this should be a decorator or a mixin.

@serializable is a decorator mainly because @dataclass is a decorator, so the dataclass fields don't exist at the time that a mixin's __init_subclass__ would execute. This limitation does not exist for Enum. As you pointed out in #42, the decorator has some drawbacks related to typing. That would suggest that the main reason to chose a decorator over a mixin would be consistency with @serializable. There is something to that, but it is not great reason. If we went that route, I would probably rename @serializable to @serializable_dataclass, create @serializable_enum, and then redefine @serializable to switch on dataclasses vs enums.

(I guess another reason would be to allow parameterization like @serializable_enum(by="value") which is awkward to do with mixins.)

If we went the mixin route, I would probably create SerializableEnumMixin and just document that it has to go after Enum in the MRO. We could create SerializableEnum, which already inherits from Enum, but then what would we do about IntEnum and StrEnum?

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.

Make serializable decorator for Enum

3 participants