I would like to create a class, which has an enumeration as an attribute. This enumeration should have a string representation that shows up as human-readable value when dumping the instance of the class that uses the enum attribute as a JSON string. In the minimal working example below, I created three enumerations in three different ways.
After the deserialization, each attribute shows us that it comes from an enumeration except the enumeration with a string representation. It is just a string.
If it is not possible to realize such a structure, I would like to know why.
Requirements
If you would like to test it, you have to install jsons and attrs with
pip install attrs jsons Minimal working example
Here you see a minimal working example.
import jsons import attr from enum import Enum # ---------------------------------------------------- # create enumeration with the help of a dictionary fruits = { "PINEAPPLE": "PINEAPPLE", "APPLE": "APPLE", "ORANGE": "ORANGE", "BANANA": "BANANA", } Fruit = Enum("FRUITS", fruits) # ---------------------------------------------------- # create a classical enumeration class Nut(Enum): PEANUT = 1 HAZELNUT = 2 CASHEW = 3 WALNUT = 4 # ---------------------------------------------------- # create enumeration with a string representation class Vegetable(str, Enum): BROCCOLI = "BROCCOLI" CUCUMBER = "CUCUMBER" POTATO = "POTATO" ONION = "ONION" # ---------------------------------------------------- # create a class which uses the enumerations @attr.s(auto_attribs=True, kw_only=True) class Order(jsons.JsonSerializable): fruit: Fruit nut: Nut vegetable: Vegetable # ---------------------------------------------------- # initialize an order object, serialize and deserialize it order = Order(fruit=Fruit.APPLE, nut=Nut.PEANUT, vegetable=Vegetable.CUCUMBER) json_string: str = Order.dumps(order) order_deserialised: Order = Order.loads(json_string) Structure of the order and order_deserialised variable:
order: Order(fruit=<FRUITS.APPLE: 'APPLE'>, nut=<Nut.PEANUT: 1>, vegetable=<Vegetable.CUCUMBER: 'CUCUMBER'>) order_deserialised: Order(fruit=<FRUITS.APPLE: 'APPLE'>, nut=<Nut.PEANUT: 1>, vegetable='CUCUMBER') As you can see, the order_deserialised shows the vegetable as a string and not an enumeration.
str???class Vegetable(str, Enum):? This is likely throwing off theattrs/jsonslibraries, somewhere I suspect, there is some checkisinstance(x, str), and it isn't handlingstrsubtypes.... "create enumeration with a string representation" That isn't a reasonable way of doing this. Just write a__str__and a__repr__method. Inheriting fromstrseems to be your issue. Your enumeration is a string, that is what inheriting fromstrdoes, so it's not surprising that it is being treated as one.str?str, soclass Vegetable(Enum): ...enumtype inherit fromstrdefeats the whole purpose ofenumin the same way as having it inherit fromint. I re-opened the question, because I don't think the duplicate was a great fit.