summaryrefslogtreecommitdiffstats
path: root/base/common/python/pki/encoder.py
blob: 06a23250ed6f1a2835d2ac830f6b653a6f9ec0ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import json

TYPES = {}
NOTYPES = {}


class CustomTypeEncoder(json.JSONEncoder):
    """A custom JSONEncoder class that knows how to encode core custom
    objects.

    Custom objects are encoded as JSON object literals (ie, dicts) with
    one key, 'TypeName' where 'TypeName' is the actual name of the
    type to which the object belongs.  That single key maps to another
    object literal which is just the __dict__ of the object encoded.

    Reason for ignoring the error
         E0202 - An attribute affected in json.encoder line 157 hide this method
       reported by pylint:

       The error is in json.encoder.JSONEncoder class.
       There is a default method (which is overridden here) and also a class
       attribute self.default initialized in the init method of the class.
       The intention of such usage being that a custom default method object can
       be passed to init when creating an instance of JSONEncoder, which is then
       assigned to class's default method. (which is valid)
       But pylint raises an issue due to the usage of same name for a method and
       an attribute in which case the attribute definition hides the method.
       The reason and example for the issue: (top rated comment)
           http://stackoverflow.com/questions/12949064/python-what-happens-
           when-instance-variable-name-is-same-as-method-name
    """
    # pylint: disable-msg=E0202
    def default(self, obj):
        for k, v in TYPES.items():
            if isinstance(obj, v):
                return {k: obj.__dict__}
        for k, v in NOTYPES.items():
            if isinstance(obj, v):
                return self.attr_name_conversion(obj.__dict__, v)
        return json.JSONEncoder.default(self, obj)

    @staticmethod
    def attr_name_conversion(attr_dict, object_class):
        if not hasattr(object_class, 'json_attribute_names'):
            return attr_dict
        for k, v in object_class.json_attribute_names.items():
            if v in attr_dict:
                value = attr_dict[v]
                del attr_dict[v]
                attr_dict[k] = value
        return attr_dict


def CustomTypeDecoder(dct):
    if len(dct) == 1:
        type_name, value = dct.items()[0]
        if type_name in TYPES:
            return TYPES[type_name].from_dict(value)
    return dct