Coverage for kye/dataset.py: 0%

87 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-05 16:38 -0700

1from __future__ import annotations 

2from kye.compiled import CompiledDataset, CompiledEdge, CompiledType, TYPE_REF, EDGE 

3from typing import Optional 

4 

5class Type: 

6 ref: TYPE_REF 

7 name: str 

8 indexes: list[list[EDGE]] 

9 extends: Optional[Type] 

10 edges: dict[EDGE, Edge] 

11 

12 def __init__(self, name: TYPE_REF): 

13 self.ref = name 

14 self.name = name 

15 self.indexes = [] 

16 self.extends = None 

17 self.edges = {} 

18 

19 @property 

20 def has_edges(self) -> bool: 

21 return len(self.edges) > 0 

22 

23 @property 

24 def has_index(self) -> bool: 

25 return len(self.indexes) > 0 

26 

27 @property 

28 def base(self) -> Optional[Type]: 

29 return self.extends if self.extends else self 

30 

31 @property 

32 def index(self) -> list[EDGE]: 

33 """ Flatten the 2d list of indexes """ 

34 return [idx for idxs in self.indexes for idx in idxs] 

35 

36 def __getitem__(self, name: EDGE) -> Edge: 

37 return self.edges[name] 

38 

39 def __contains__(self, name: EDGE) -> bool: 

40 return name in self.edges 

41 

42 def __iter__(self) -> iter[Edge]: 

43 return iter(self.edges.values()) 

44 

45 def __repr__(self): 

46 return "Type<{}>".format(self.ref) 

47 

48class Edge: 

49 name: EDGE 

50 

51 def __init__(self, name: EDGE, edge: CompiledEdge, model: DefinedType): 

52 self.ref = model.ref + '.' + name 

53 self.name = name 

54 self._edge = edge 

55 self._model = model 

56 

57 @property 

58 def multiple(self) -> bool: 

59 return self._edge.multiple 

60 

61 @property 

62 def nullable(self) -> bool: 

63 return self._edge.nullable 

64 

65 @property 

66 def is_index(self) -> bool: 

67 return self.name in self._model.index 

68 

69 @property 

70 def type(self) -> Type: 

71 return self._model._models[self._edge.type] 

72 

73 def __repr__(self): 

74 return 'Edge<{}:{}{}>'.format( 

75 self.ref, 

76 self.type.name or '', 

77 ([['' ,'+'], 

78 ['?','*']])[int(self.nullable)][int(self.multiple)] 

79 ) 

80 

81class DefinedType(Type): 

82 def __init__(self, ref: TYPE_REF, type: CompiledType, models: Models): 

83 self.ref = ref 

84 self._type = type 

85 self._models = models 

86 

87 self.edges = { 

88 name: Edge(name, edge, self) 

89 for name, edge in self._type.edges.items() 

90 } 

91 for parent in self.parents(): 

92 for edge in parent.edges.values(): 

93 if edge.name not in self.edges: 

94 self.edges[edge.name] = edge 

95 

96 @property 

97 def name(self): 

98 return self._type.name if self._type.name else self.extends.name 

99 

100 @property 

101 def indexes(self): 

102 return self._type.indexes if self._type.indexes else self.extends.indexes 

103 

104 @property 

105 def extends(self): 

106 return self._models[self._type.extends] if self._type.extends else None 

107 

108 def parents(self): 

109 if self.extends: 

110 return [ self.extends ] + self.extends.parents() 

111 return [] 

112 

113 def __repr__(self): 

114 return repr(self._type) 

115 

116class Models: 

117 globals = { 

118 'Number': Type('Number'), 

119 'String': Type('String'), 

120 'Boolean': Type('Boolean'), 

121 'Struct': Type('Struct'), 

122 'Model': Type('Model'), 

123 } 

124 

125 def __init__(self, models: CompiledDataset): 

126 self._models = models 

127 

128 def __getitem__(self, ref: TYPE_REF): 

129 if ref in self.globals: 

130 return self.globals[ref] 

131 if ref in self._models: 

132 return DefinedType(ref, self._models[ref], self) 

133 raise KeyError(ref) 

134 

135 def __contains__(self, ref: TYPE_REF): 

136 return ref in self.globals or ref in self._models 

137 

138 def __repr__(self): 

139 return repr(self._models)