Coverage for kye/dataset.py: 59%
87 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-13 15:17 -0700
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-13 15:17 -0700
1from __future__ import annotations
2from kye.compiled import CompiledDataset, CompiledEdge, CompiledType, TYPE_REF, EDGE
3from typing import Optional
5class Type:
6 ref: TYPE_REF
7 name: str
8 indexes: list[list[EDGE]]
9 extends: Optional[Type]
10 edges: dict[EDGE, Edge]
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 = {}
19 @property
20 def has_edges(self) -> bool:
21 return len(self.edges) > 0
23 @property
24 def has_index(self) -> bool:
25 return len(self.indexes) > 0
27 @property
28 def base(self) -> Optional[Type]:
29 return self.extends if self.extends else self
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]
36 def __getitem__(self, name: EDGE) -> Edge:
37 return self.edges[name]
39 def __contains__(self, name: EDGE) -> bool:
40 return name in self.edges
42 def __iter__(self) -> iter[Edge]:
43 return iter(self.edges.values())
45 def __repr__(self):
46 return "Type<{}>".format(self.ref)
48class Edge:
49 name: EDGE
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
57 @property
58 def multiple(self) -> bool:
59 return self._edge.multiple
61 @property
62 def nullable(self) -> bool:
63 return self._edge.nullable
65 @property
66 def is_index(self) -> bool:
67 return self.name in self._model.index
69 @property
70 def type(self) -> Type:
71 return self._model._models[self._edge.type]
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 )
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
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
96 @property
97 def name(self):
98 return self._type.name if self._type.name else self.extends.name
100 @property
101 def indexes(self):
102 return self._type.indexes if self._type.indexes else self.extends.indexes
104 @property
105 def extends(self):
106 return self._models[self._type.extends] if self._type.extends else None
108 def parents(self):
109 if self.extends:
110 return [ self.extends ] + self.extends.parents()
111 return []
113 def __repr__(self):
114 return repr(self._type)
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 }
125 def __init__(self, models: CompiledDataset):
126 self._models = models
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)
135 def __contains__(self, ref: TYPE_REF):
136 return ref in self.globals or ref in self._models
138 def __repr__(self):
139 return repr(self._models)