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

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""" 

20 

21import json 

22 

23 

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 

92 

93 

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] 

104 

105 return d