Skip to content

Option for calling default method for dictionaries with non string keys possible ?  #150

Description

@SmartAudioTools

In order to allow serializejson to serialize dictionaries with no string keys, and enable serializejson to be a drop-in replacement for the Python pickle package, I wonder if it would be possible to add an option for automatically check if dictionaries contains only string keys, and call the "default" method if not, instead of raising a "TypeError: keys must be strings" .

In the following code, I'm able to serialize a dictionary containing non string keys, by simulating call to default method for this dictionary.

from serializejson import dumps,loads

def default(inst): 
    if isinstance(inst,dict):
        return {
              "__class__":"__main__.dict_json_keys",
              "__init__": {dumps(key,indent=None):value for key, value in inst.items()}
             } 
    return inst
        
def dict_json_keys(**args):
    return {loads(key):value for key,value in args.items()}
        
obj = {
        "string" : "str",
        b"bytes" : "bytes",
        True: "bool" , 
        2 : "int",
        3.4 : "float",
        (5,6) : "tuple",
        frozenset([7,8]) : "frozenset"
    }
print(obj)
"""{'string': 'str', b'bytes': 'bytes', True: 'bool', 2: 'int', 3.4: 'float', (5, 6): 'tuple', frozenset({8, 7}): 'frozenset'}"""

dumped = dumps(default(obj))

"""
{
    "__class__": "__main__.dict_json_keys",
    "__init__": {
            "\"string\"": "str",
            "2": "int",
            "3.4": "float",
            "true": "bool",
            "{\"__class__\":\"bytes\",\"__init__\":[\"bytes\",\"ascii\"]}": "bytes",
            "{\"__class__\":\"frozenset\",\"__init__\":[8,7]}": "frozenset",
            "{\"__class__\":\"tuple\",\"__init__\":[5,6]}": "tuple"
    }
}
"""

print(dumped)    
loaded = loads(dumped,authorized_classes = [dict_json_keys])
assert obj == loaded

Maybe dictionaries returned by default should not be checked for only string keys, to avoid double checking and consuming too much cpu.
In addition, we should check before starting to serialize a dictionary, rather than calling default only when it encounters a TypeError, because if you write in a file stream, we will not be able to go back if we have started to serialize the beginning of the dictionary.

What do you think about it ?
Do you think it's feasible ?

Thank you very much for your amazing python-rapidjson package .

Baptiste

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions