json.dumps() encodes StrEnum with custom __new__ to empty string

Question:

I have an enum similar to the following:

from enum import Enum


class Currencies(str, Enum):
    EURO = ("EUR", True)
    YEN = ("JPY", False)

    supports_decimals: bool

    def __new__(cls, value: str, supports_decimals: bool):
        obj = super().__new__(cls)
        obj._value_ = value
        setattr(obj, "supports_decimals", supports_decimals)

        return obj

This allows things like:

>>> Currencies.EURO.value
'EUR'
>>> Currencies.EURO.supports_decimals
True
>>> f"{Currencies.EURO}"
'EUR'

However:

>>> import json
>>> json.dumps(Currencies.EUR)
'""'

This would work if my enum had simple string members instead of tuples, but instead it results in empty strings, and since the enum’s members are seen as str, a custom encoder class doesn’t call .default() on them at all, so I can’t define a custom encoding for them.

The problem likely comes down to str.encode(), because indeed:

>>> Currencies.EUR.encode()
b''

But even knowing that, I don’t know how I could instruct json.dumps() to use the member’s _value_. I tried overriding encode() and that makes Currencies.EUR.encode() work, but json.dumps() still returns an empty string.

Note that I’d rather keep the enum a str, Enum because turning it into a simple Enum would complicate other parts of my application.

Asked By: theberzi

||

Answers:

Your enum instances are empty strings. obj = super().__new__(cls) makes an instance that is an empty string.

Make a nonempty string:

obj = super().__new__(cls, value)
Answered By: user2357112
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.