Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct that contains an Enum property with a metaclass cant be decoded #822

Open
Jonxslays opened this issue Mar 7, 2025 · 1 comment · May be fixed by #824
Open

Struct that contains an Enum property with a metaclass cant be decoded #822

Jonxslays opened this issue Mar 7, 2025 · 1 comment · May be fixed by #824

Comments

@Jonxslays
Copy link

Jonxslays commented Mar 7, 2025

Description

I don't know if this is a bug, or just something that can't be supported. I've reviewed some of the other issues surrounding metaclasses and it seems there isn't a workaround.

This case is a little different though, my classes which inherit from Struct do not define a metaclass - but instead they have a property which is a subclass of Enum with a metaclass.

I put together a minimal reproducible example. Is it possible to support this use case?

from enum import Enum, EnumMeta

import msgspec


class BaseEnumSuccess(Enum):
    ...


class BaseEnumMeta(EnumMeta):
    ...


class BaseEnumFail(Enum, metaclass=BaseEnumMeta):
    ...


class EnumSuccess(BaseEnumSuccess):
    Success = "success"


class EnumFail(BaseEnumFail):
    Success = "success"


class TesterSuccess(msgspec.Struct):
    variant: EnumSuccess


class TesterFail(msgspec.Struct):
    variant: EnumFail


decoder_success = msgspec.json.Decoder(TesterSuccess)
decoded_success = decoder_success.decode(b'{"variant": "success"}')
print(decoded_success)

decoder_fail = msgspec.json.Decoder(TesterFail)
decoded_fail = decoder_fail.decode(b'{"variant": "success"}')
print(decoded_fail)

Output:

TesterSuccess(variant=<EnumSuccess.Success: 'success'>)
Traceback (most recent call last):
  File "/home/jonx/projects/py/example.py", line 39, in <module>
    decoded_fail = decoder_fail.decode(b'{"variant": "success"}')
msgspec.ValidationError: Expected `EnumFail`, got `str` - at `$.variant`

Version info:

----------------------------------------------
Msgspec:     0.19.0
----------------------------------------------
Interpreter: CPython 3.13.1
----------------------------------------------
Compiler:    GCC 14.2.1 20240910
----------------------------------------------
OS/Arch:     Linux 6.6.72-1-lts / x86_64
----------------------------------------------

Thanks in advance for your time, love the library - it massively improved performance for me.

@UnknownPlatypus
Copy link

I'm having a similar issue when using msgspec with django TextChoices.

A minimal reproducible example:

import msgspec
from django.db import models

class SomeEnum(models.TextChoices):  # class TextChoices(str, enum.Enum, metaclass=ChoicesMeta)
    EXAMPLE_VALUE = "hello"

class SomeModel(msgspec.Struct):
    values: SomeEnum


msgspec.json.encode(SomeModel(SomeEnum.EXAMPLE_VALUE))
# TypeError: Encoding objects of type SomeEnum is unsupported

I'd love to give some help if it makes sense for this

@UnknownPlatypus UnknownPlatypus linked a pull request Mar 15, 2025 that will close this issue
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 a pull request may close this issue.

2 participants