Coverage for skema/utils/fold.py: 21%
61 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 17:15 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 17:15 +0000
1"""Helper functions for pretty-printing Gromet Json output.
2Example:
3{
4 "function_networks": [
5 {
6 "B": [{"name":"module","type":"Module"}],
7 "BF": [{"contents":1,"name":"","type":"Expression"}],
8 "POF": [{"box":0,"name":"x"}]
9 },
10 {
11 "B": [{"name":"","type":"Expression"}],
12 "BF": [{"name":"","type":"LiteralValue","value":{"value":2,"value_type":"Integer"}}],
13 "OPO": [{"box":0,"name":"x"}],
14 "POF": [{"box":0,"name":""}],
15 "WFOPO": [{"src":0,"tgt":0}]
16 }
17 ]
18}
19"""
21import json
24def dictionary_to_gromet_json(
25 o, fold_level=5, indent=4, level=0, parent_key=""
26):
27 if level < fold_level:
28 newline = "\n"
29 space = " "
30 else:
31 newline = ""
32 space = ""
33 ret = ""
34 if isinstance(o, str):
35 ret += json.dumps(
36 o
37 ) # json.dumps() will properly escape special characters
38 elif isinstance(o, bool):
39 ret += "true" if o else "false"
40 elif isinstance(o, float):
41 ret += "%.7g" % o
42 elif isinstance(o, int):
43 ret += str(o)
44 elif isinstance(o, list):
45 ret += "[" + newline
46 comma = ""
47 for e in o:
48 ret += comma
49 comma = "," + newline
50 ret += space * indent * (level + 1)
51 ret += dictionary_to_gromet_json(
52 e, fold_level, indent, level + 1, parent_key
53 )
54 ret += newline + space * indent * level + "]"
55 elif isinstance(o, dict):
56 ret += "{" + newline
57 comma = ""
58 for k, v in o.items():
59 ret += comma
60 comma = "," + newline
61 ret += space * indent * (level + 1)
62 ret += '"' + str(k) + '":' + space
63 if k == "fn":
64 ret += dictionary_to_gromet_json(v, 4, indent, level + 1, k)
65 elif k == "attributes":
66 ret += dictionary_to_gromet_json(v, 6, indent, level + 1, k)
67 elif k == "bf" and parent_key == "fn":
68 ret += dictionary_to_gromet_json(v, 5, indent, level + 1, k)
69 elif k == "bf" and parent_key == "value":
70 ret += dictionary_to_gromet_json(v, 7, indent, level + 1, k)
71 else:
72 ret += dictionary_to_gromet_json(
73 v, fold_level, indent, level + 1, k
74 )
75 ret += newline + space * indent * level + "}"
76 elif o is None:
77 ret += "null"
78 else:
79 # NOTE: We added this check here to catch any Python objects that
80 # didn't get turned into dictionaries.
81 # This is to circumvent Swagger's inability to generate to_dicts that support
82 # multi-dimensional dictionaries. This becomes an issue for us when we're storing
83 # an array of metadata arrays
84 if hasattr(o, "to_dict"):
85 temp = del_nulls(o.to_dict())
86 ret += dictionary_to_gromet_json(
87 temp, fold_level, indent, level, parent_key
88 )
89 else:
90 ret += str(o)
91 return ret
94def del_nulls(d):
95 for key, value in list(d.items()):
96 if isinstance(value, list):
97 for elem in value:
98 if isinstance(elem, dict):
99 del_nulls(elem)
100 if isinstance(value, dict):
101 del_nulls(value)
102 if value is None:
103 del d[key]
105 return d