ato 2.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ato/xyz.py ADDED
@@ -0,0 +1,234 @@
1
+ import os
2
+ from typing import Iterable
3
+
4
+ from ato.utils import convert_string_to_value
5
+
6
+
7
+ class GlobalParser:
8
+ def __init__(self, value, value_type, parent=None, format_dict=None):
9
+ self.value = int(value) if value_type == 'index' else value
10
+ self.node_type = 'value' # initialized to value
11
+ self.value_type = value_type # Type of the node (either 'key', 'index', or 'value')
12
+ self.parent = parent # Parent node
13
+ self.children = [] # List to hold children nodes
14
+ self.format_dict = format_dict
15
+
16
+ def add_child(self, child_node):
17
+ self.children.append(child_node)
18
+ child_node.parent = self
19
+ if child_node.value_type == 'key':
20
+ self.node_type = 'dict'
21
+ elif child_node.value_type == 'index':
22
+ self.node_type = 'iter'
23
+ else:
24
+ self.node_type = 'item'
25
+
26
+ def dumps(self, level=None):
27
+ decoding_format_str = ''
28
+ if self.format_dict:
29
+ if self.parent is None:
30
+ for key, value in self.format_dict.items():
31
+ decoding_format_str += f'{key} -> {value}'
32
+ decoding_format_str += '\n'
33
+ prefix = self.format_dict.get(f'{self.value_type}_prefix', '')
34
+ postfix = self.format_dict.get(f'{self.value_type}_postfix', '')
35
+ if self.value_type == 'key':
36
+ postfix = postfix or ':'
37
+ elif self.value_type == 'index':
38
+ postfix = postfix or ')'
39
+ else:
40
+ prefix = ''
41
+ if self.value_type == 'key':
42
+ postfix = ':'
43
+ elif self.value_type == 'index':
44
+ postfix = ')'
45
+ else:
46
+ postfix = ''
47
+ xyz_raw_str = ''
48
+ if self.parent:
49
+ xyz_raw_str += ' '*level+prefix+str(self.value)+postfix
50
+ else:
51
+ level = -1
52
+ if not self.children:
53
+ if self.node_type == 'iter':
54
+ xyz_raw_str += ' [Empty Sequence]'
55
+ elif self.node_type == 'dict':
56
+ xyz_raw_str += ' [Empty Mapping]'
57
+ for child in self.children:
58
+ if child.value_type != 'value':
59
+ xyz_raw_str += '\n'+child.dumps(level+1)
60
+ else:
61
+ child_value = f'{child.value}' if isinstance(child.value, str) else str(child.value)
62
+ xyz_raw_str += ' '+child_value
63
+ xyz_raw_str = decoding_format_str+xyz_raw_str
64
+ # If decoding format is empty, remove first line break
65
+ if xyz_raw_str and xyz_raw_str[0] == '\n':
66
+ xyz_raw_str = xyz_raw_str[1:]
67
+ return xyz_raw_str
68
+
69
+ def __repr__(self):
70
+ return f'Node({", ".join([f"{name}={value}" for name, value in vars(self).items()])})'
71
+
72
+
73
+ # Modifying function to handle custom postfix for keys and indices more dynamically
74
+ def convert_lines_to_tree(lines, format_dict=None):
75
+ root = GlobalParser('root', 'key')
76
+ current_node = root
77
+ current_indent = -1
78
+
79
+ format_dict = format_dict or dict()
80
+ key_prefix = format_dict.get('key_prefix', '')
81
+ key_postfix = format_dict.get('key_postfix', ':')
82
+ index_prefix = format_dict.get('index_prefix', '')
83
+ index_postfix = format_dict.get('index_postfix', ')')
84
+
85
+ while lines:
86
+ line = lines.pop(0)
87
+ line = line.rstrip()
88
+ indent = len(line)-len(line.lstrip())
89
+ stripped_line = line.strip()
90
+
91
+ # Conditions for custom prefix and postfix
92
+ prefix_cond = lambda prefix: (not prefix or stripped_line.startswith(prefix))
93
+ postfix_cond = lambda postfix: postfix in stripped_line
94
+
95
+ while current_node and indent <= current_indent:
96
+ current_node = current_node.parent
97
+ current_indent -= 2 # Assuming 2 spaces for each indent level
98
+ if prefix_cond(key_prefix) and postfix_cond(key_postfix):
99
+ tokens = stripped_line.split(key_postfix)
100
+ key = tokens.pop(0).strip()[len(key_prefix):]
101
+ new_node = GlobalParser(key, 'key', current_node)
102
+ current_node.add_child(new_node)
103
+ current_node = new_node
104
+ current_indent = indent
105
+ if tokens[0]:
106
+ indent += 2
107
+ lines = [' '*indent+key_postfix.join(tokens).strip()]+lines
108
+ elif prefix_cond(index_prefix) and postfix_cond(index_postfix):
109
+ tokens = stripped_line.split(index_postfix)
110
+ index = tokens.pop(0).strip()[len(index_prefix):]
111
+ new_node = GlobalParser(index, 'index', current_node)
112
+ current_node.add_child(new_node)
113
+ current_node = new_node
114
+ current_indent = indent
115
+ if tokens[0]:
116
+ indent += 2
117
+ lines = [' '*indent+index_postfix.join(tokens).strip()]+lines
118
+ else:
119
+ value = convert_string_to_value(stripped_line)
120
+ new_node = GlobalParser(value, 'value', current_node)
121
+ current_node.add_child(new_node)
122
+ current_node = new_node.parent
123
+ # Remove the root node from the tree
124
+ return root
125
+
126
+
127
+ def convert_structure_to_tree(struct, root=None, format_dict=None):
128
+ format_dict = format_dict or dict()
129
+ if root is None:
130
+ root = GlobalParser('root', 'key', None, format_dict=format_dict)
131
+ if isinstance(struct, dict):
132
+ root.node_type = 'dict'
133
+ value_type = 'key'
134
+ elif isinstance(struct, Iterable) and not isinstance(struct, str):
135
+ root.node_type = 'iter'
136
+ value_type = 'index'
137
+ else:
138
+ root.node_type = 'item'
139
+ value_node = GlobalParser(struct, 'value', root, None)
140
+ value_node.node_type = 'value'
141
+ root.add_child(value_node)
142
+ return root
143
+ for index, value in enumerate(struct):
144
+ if root.node_type == 'dict':
145
+ key = value
146
+ else:
147
+ key = index
148
+ child_struct = struct[key]
149
+ child = GlobalParser(key, value_type, root, format_dict)
150
+ root.add_child(convert_structure_to_tree(child_struct, child, format_dict))
151
+ return root
152
+
153
+
154
+ def convert_tree_to_structure(root):
155
+ if root.node_type == 'item':
156
+ return root.children[0].value
157
+ elif root.node_type == 'dict':
158
+ children_dict = {}
159
+ for child in root.children:
160
+ children_dict[child.value] = convert_tree_to_structure(child)
161
+ return children_dict
162
+ elif root.node_type == 'iter':
163
+ size = max([child.value+1 for child in root.children])
164
+ children_list = [None]*size
165
+ for child in root.children:
166
+ children_list[child.value] = convert_tree_to_structure(child)
167
+ return children_list
168
+
169
+
170
+ def parse_lines(lines):
171
+ decoding_formats = []
172
+ data_lines = []
173
+ for line in lines:
174
+ is_decoding_format = any(
175
+ map(lambda text: line.startswith(text), ('key-prefix', 'key-postfix', 'index-prefix', 'index-postfix'))
176
+ )
177
+ if is_decoding_format:
178
+ decoding_formats.append(line)
179
+ else:
180
+ data_lines.append(line)
181
+ return decoding_formats, data_lines
182
+
183
+
184
+ def parse_format(decoding_formats):
185
+ key_prefix = index_prefix = ''
186
+ key_postfix = ':'
187
+ index_postfix = ')'
188
+ for line in decoding_formats:
189
+ line = line.strip()
190
+ if line.startswith('key-prefix'):
191
+ key_prefix = line[len('key-prefix -> '):].strip()
192
+ elif line.startswith('key-postfix'):
193
+ key_postfix = line[len('key-postfix -> '):].strip()
194
+ elif line.startswith('index-prefix'):
195
+ index_prefix = line[len('index-prefix -> '):].strip()
196
+ elif line.startswith('index-postfix'):
197
+ index_postfix = line[len('index-postfix -> '):].strip()
198
+ return dict(key_prefix=key_prefix, key_postfix=key_postfix, index_prefix=index_prefix, index_postfix=index_postfix)
199
+
200
+
201
+ def remove_format_str(raw_str):
202
+ return '\n'.join(parse_lines(raw_str.strip().split('\n'))[1])
203
+
204
+
205
+ def loads(raw_str):
206
+ lines = raw_str.strip().split('\n')
207
+ decoding_formats, lines = parse_lines(lines)
208
+ format_dict = parse_format(decoding_formats)
209
+ root = convert_lines_to_tree(lines, format_dict)
210
+ return convert_tree_to_structure(root)
211
+
212
+
213
+ def dumps(obj, format_dict=None):
214
+ return convert_structure_to_tree(obj, format_dict=format_dict).dumps()
215
+
216
+
217
+ def dump(obj, path_or_file, format_dict=None):
218
+ if isinstance(path_or_file, (str, os.PathLike)):
219
+ with open(path_or_file, 'w') as f:
220
+ f.write(dumps(obj, format_dict=format_dict))
221
+ else:
222
+ path_or_file.write(dumps(obj, format_dict=format_dict))
223
+
224
+
225
+ def load(path_or_file):
226
+ if isinstance(path_or_file, (str, os.PathLike)):
227
+ with open(path_or_file, 'r') as f:
228
+ lines = list(f.readlines())
229
+ else:
230
+ lines = list(path_or_file.readlines())
231
+ decoding_formats, lines = parse_lines(lines)
232
+ format_dict = parse_format(decoding_formats)
233
+ root = convert_lines_to_tree(lines, format_dict=format_dict)
234
+ return convert_tree_to_structure(root)