Open rupert-madden-abbott opened 3 years ago
I have a similar scenario (mixed value types only for experimentation).
class WeekDay(Enum):
MONDAY = "MON"
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 7
example: Dict[WeekDay, int]
example = {
WeekDay.MONDAY: 10,
WeekDay.SUNDAY: 1
}
print(example)
dumped = jsons.dumps(example, strict=True, use_enum_name=False)
print(dumped)
deserialized = jsons.loads(dumped, Dict[WeekDay, int], use_enum_name=False)
print(deserialized)
De-serialization of the serialized form does work as expected:
{<WeekDay.MONDAY: 'MON'>: 10, <WeekDay.SUNDAY: 7>: 1}
{"-keys": {"6161275848482540713": "MON", "7973924388498358727": 7}, "6161275848482540713": 10, "7973924388498358727": 1}
{<WeekDay.MONDAY: 'MON'>: 10, <WeekDay.SUNDAY: 7>: 1}
Admittedly, the serialized form of a dict with Enum keys does look a little odd. But it seems they need to make sure the keys are valid types for Python's JSON. Search the code for "if not any(issubclass(type(key), json_key) for json_key in JSON_KEYS)".
I think you should rephrase the issue's title into "A dict with Enum keys serialized representation does not look the way I like". This way, you can argue the beauty of the representation (along the lines "readability counts", compatibility with external systems, use of de-serialization libs other than JSON). But for as long as you want to dump into JSON format, you need to make sure that the keys are of acceptable types.
@swissguest
Admittedly, the serialized form of a dict with Enum keys does look a little odd. But it seems they need to make sure the keys are valid types for Python's JSON.
Why is that? Enums are serialised to strings when they are not dict keys.
I think swissguest answered it nicely. 💐
Python allows more types as keys in dicts than json allows keys in objects. As you know, anything that is hashable in Python can be used as a key in a dict, whereas json allows only strings, integers, floats, booleans or null.
jsons
uses the object's hash to still be able to dump dicts with keys that would not be valid in json. Enumerations are no exception to this, that's why you get the output you described.
I'm not against making an exception for enumerations though, as I agree that your expected outcome would be nicer to read. However, it would encompass also featuring a new argument to the load
function. Because upon loading, you would need to somehow tell jsons
to load the keys of the source into your enum. Something like this:
jsons.load(dumped, cls=SomeClass, key_cls=SomeEnum)
Example
Expected Output
Actual Output The enum keys are hashed and the hashes are used in place of the actual keys whilst an additional "-keys" map is added with the hashes back to the original values.