omlish 0.0.0.dev305__py3-none-any.whl → 0.0.0.dev306__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.
omlish/.manifests.json CHANGED
@@ -51,6 +51,20 @@
51
51
  }
52
52
  }
53
53
  },
54
+ {
55
+ "module": ".formats.edn.codec",
56
+ "attr": "_EDN_LAZY_CODEC",
57
+ "file": "omlish/formats/edn/codec.py",
58
+ "line": 25,
59
+ "value": {
60
+ "$.codecs.base.LazyLoadedCodec": {
61
+ "mod_name": "omlish.formats.edn.codec",
62
+ "attr_name": "EDN_CODEC",
63
+ "name": "edn",
64
+ "aliases": null
65
+ }
66
+ }
67
+ },
54
68
  {
55
69
  "module": ".formats.ini.codec",
56
70
  "attr": "_INI_LAZY_CODEC",
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev305'
2
- __revision__ = '13f1bfc223e6af63310421aa4ac6133b3f1e0110'
1
+ __version__ = '0.0.0.dev306'
2
+ __revision__ = 'dda70244f84192bfce2428b682f9a5e2349fb05a'
3
3
 
4
4
 
5
5
  #
@@ -101,7 +101,7 @@ class Project(ProjectBase):
101
101
 
102
102
  'apsw ~= 3.49',
103
103
 
104
- 'sqlean.py ~= 3.47',
104
+ 'sqlean.py ~= 3.49',
105
105
 
106
106
  'duckdb ~= 1.2',
107
107
  ],
@@ -0,0 +1,16 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Jorin Vogel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ persons to whom the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ from .parsing import ( # Noqa
2
+ parse,
3
+ parse_list,
4
+ )
5
+
6
+ from .values import ( # noqa
7
+ Char,
8
+ Keyword,
9
+ List,
10
+ Map,
11
+ Set,
12
+ Symbol,
13
+ TaggedVal,
14
+ Vector,
15
+ )
@@ -0,0 +1,26 @@
1
+ import typing as ta
2
+
3
+ from ..codecs import make_object_lazy_loaded_codec
4
+ from ..codecs import make_str_object_codec
5
+ from .parsing import parse
6
+
7
+
8
+ ##
9
+
10
+
11
+ def dumps(obj: ta.Any) -> str:
12
+ # return json.dumps(obj)
13
+ raise NotImplementedError
14
+
15
+
16
+ def loads(s: str) -> ta.Any:
17
+ return parse(s)
18
+
19
+
20
+ ##
21
+
22
+
23
+ EDN_CODEC = make_str_object_codec('edn', dumps, loads)
24
+
25
+ # @omlish-manifest
26
+ _EDN_LAZY_CODEC = make_object_lazy_loaded_codec(__name__, 'EDN_CODEC', EDN_CODEC)
@@ -0,0 +1,359 @@
1
+ """
2
+ TODO:
3
+ - reader meta - ^:foo
4
+ """
5
+ # https://github.com/jorinvo/edn-data/blob/1e5824f63803eb58f35e98839352000053d47115/test/parse.test.ts
6
+ import datetime
7
+ import enum
8
+ import re
9
+ import typing as ta
10
+
11
+ from ... import check
12
+ from .values import Char
13
+ from .values import Keyword
14
+ from .values import List
15
+ from .values import Map
16
+ from .values import Set
17
+ from .values import Symbol
18
+ from .values import TaggedVal
19
+ from .values import Vector
20
+
21
+
22
+ ##
23
+
24
+
25
+ class ListParser:
26
+ DEFAULT_TAG_HANDLERS: ta.ClassVar[ta.Mapping[str, ta.Callable[..., ta.Any]]] = {
27
+ 'inst': lambda val: datetime.datetime.fromisoformat(val) if isinstance(val, str) else None,
28
+ }
29
+
30
+ def __init__(
31
+ self,
32
+ *,
33
+ keyword_maker: ta.Callable[..., ta.Any] = Keyword,
34
+ char_maker: ta.Callable[..., ta.Any] = Char,
35
+ symbol_maker: ta.Callable[..., ta.Any] = Symbol,
36
+
37
+ list_maker: ta.Callable[..., ta.Any] = List.new,
38
+ vector_maker: ta.Callable[..., ta.Any] = Vector.new,
39
+ set_maker: ta.Callable[..., ta.Any] = Set.new,
40
+ map_maker: ta.Callable[..., ta.Any] = Map.new,
41
+
42
+ tag_handlers: ta.Mapping[str, ta.Callable[..., ta.Any]] | None = None,
43
+ ) -> None:
44
+ super().__init__()
45
+
46
+ self._keyword_maker = keyword_maker
47
+ self._char_maker = char_maker
48
+ self._symbol_maker = symbol_maker
49
+
50
+ self._list_maker = list_maker
51
+ self._vector_maker = vector_maker
52
+ self._set_maker = set_maker
53
+ self._map_maker = map_maker
54
+
55
+ self._tag_handlers = {
56
+ **self.DEFAULT_TAG_HANDLERS,
57
+ **(tag_handlers or {}),
58
+ }
59
+
60
+ self._stack: list[tuple[ListParser._ParseMode | ListParser._StackItem, ta.Any]] = []
61
+ self._mode: ListParser._ParseMode = ListParser._ParseMode.IDLE
62
+ self._state = ''
63
+ self._result: ta.Any = self._UNDEFINED
64
+
65
+ #
66
+
67
+ class _UNDEFINED: # noqa
68
+ def __new__(cls, *args, **kwargs): # noqa
69
+ raise TypeError
70
+
71
+ class _ParseMode(enum.Enum):
72
+ IDLE = 0
73
+ STRING = 1
74
+ ESCAPE = 2
75
+ COMMENT = 3
76
+
77
+ class _StackItem(enum.Enum):
78
+ VECTOR = 0
79
+ LIST = 1
80
+ MAP = 2
81
+ SET = 3
82
+ TAG = 4
83
+
84
+ #
85
+
86
+ def _update_stack(self) -> None:
87
+ if not self._stack or self._result is self._UNDEFINED:
88
+ return
89
+
90
+ stack_item, prev_state = self._stack[-1]
91
+
92
+ if stack_item == ListParser._StackItem.VECTOR:
93
+ prev_state.append(self._result)
94
+
95
+ elif stack_item == ListParser._StackItem.LIST:
96
+ prev_state.append(self._result)
97
+
98
+ elif stack_item == ListParser._StackItem.SET:
99
+ prev_state.append(self._result)
100
+
101
+ elif stack_item == ListParser._StackItem.MAP:
102
+ if len(prev_state[1]) > 0:
103
+ prev_state[0].append([prev_state[1].pop(), self._result])
104
+ else:
105
+ prev_state[1].append(self._result)
106
+
107
+ elif stack_item == ListParser._StackItem.TAG:
108
+ self._stack.pop()
109
+
110
+ if prev_state == '_':
111
+ self._result = self._UNDEFINED
112
+
113
+ else:
114
+ tag_handler = self._tag_handlers.get(prev_state)
115
+ if tag_handler:
116
+ self._result = tag_handler(self._result)
117
+ else:
118
+ self._result = TaggedVal(prev_state, self._result)
119
+
120
+ self._update_stack()
121
+ return
122
+
123
+ # TODO: else error
124
+ # Reset result after updating stack
125
+ self._result = self._UNDEFINED
126
+
127
+ #
128
+
129
+ _INT_PAT = re.compile(r'^[-+]?(0|[1-9][0-9]*)$')
130
+ _BIGINT_PAT = re.compile(r'^[-+]?(0|[1-9][0-9]*)N$')
131
+ _FLOAT_PAT = re.compile(r'^[-+]?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?(0|[1-9][0-9]*))?M?$')
132
+
133
+ def _match(self) -> None:
134
+ if self._state == 'nil':
135
+ self._result = None
136
+
137
+ elif self._state == 'true':
138
+ self._result = True
139
+
140
+ elif self._state == 'false':
141
+ self._result = False
142
+
143
+ elif self._state.startswith(':'):
144
+ # Keyword
145
+ self._result = self._keyword_maker(self._state[1:])
146
+
147
+ elif self._state.startswith('#'):
148
+ # Tag
149
+ self._stack.append((ListParser._StackItem.TAG, self._state[1:]))
150
+ self._result = self._UNDEFINED
151
+
152
+ elif self._INT_PAT.match(self._state):
153
+ # Int
154
+ self._result = int(self._state)
155
+
156
+ elif self._FLOAT_PAT.match(self._state):
157
+ # Float
158
+ self._result = float(self._state)
159
+
160
+ elif self._BIGINT_PAT.match(self._state):
161
+ # BigInt
162
+ self._result = int(self._state[:-1]) # In Python we don't need special handling for bigint
163
+
164
+ elif self._state.startswith('\\'):
165
+ # Char
166
+ check.state(len(self._state) > 1)
167
+ if self._state == '\\space':
168
+ c = ' '
169
+ elif self._state == '\\newline':
170
+ c = '\n'
171
+ elif self._state == '\\return':
172
+ c = '\r'
173
+ elif self._state == '\\tab':
174
+ c = '\t'
175
+ elif self._state == '\\\\':
176
+ c = '\\'
177
+ elif self._state.startswith('\\u'):
178
+ check.state(len(self._state) == 6)
179
+ c = chr(int(self._state[2:], 16))
180
+ else:
181
+ check.state(len(self._state) == 2)
182
+ c = self._state[1:]
183
+
184
+ self._result = self._char_maker(c)
185
+
186
+ elif self._state:
187
+ # Symbol
188
+ self._result = self._symbol_maker(self._state)
189
+
190
+ self._state = ''
191
+
192
+ #
193
+
194
+ _SPACE_CHARS: ta.ClassVar[ta.AbstractSet[str]] = frozenset([',', ' ', '\t', '\n', '\r'])
195
+
196
+ _STRING_ESCAPE_MAP: ta.ClassVar[ta.Mapping[str, str]] = {
197
+ 't': '\t',
198
+ 'r': '\r',
199
+ 'n': '\n',
200
+ '\\': '\\',
201
+ '"': '"',
202
+ }
203
+
204
+ def parse(self, src: str) -> list[ta.Any]:
205
+ values = []
206
+
207
+ i = -1
208
+ for i in range(len(src)):
209
+ if not self._stack and self._result is not self._UNDEFINED:
210
+ values.append(self._result)
211
+ self._result = self._UNDEFINED
212
+
213
+ char = src[i]
214
+
215
+ if self._mode == ListParser._ParseMode.IDLE:
216
+ if char == '"':
217
+ self._match()
218
+ self._update_stack()
219
+ self._mode = ListParser._ParseMode.STRING
220
+ self._state = ''
221
+ continue
222
+
223
+ if char == ';':
224
+ self._mode = ListParser._ParseMode.COMMENT
225
+ continue
226
+
227
+ if char in self._SPACE_CHARS:
228
+ self._match()
229
+ self._update_stack()
230
+ continue
231
+
232
+ if char == '}':
233
+ self._match()
234
+ self._update_stack()
235
+
236
+ if self._stack:
237
+ stack_item, prev_state = self._stack.pop()
238
+
239
+ if stack_item == ListParser._StackItem.MAP:
240
+ check.empty(prev_state[1])
241
+ self._result = self._map_maker(prev_state[0])
242
+
243
+ else: # Set
244
+ # FIXME:
245
+ # check.state(stack_item == ListParser._StackItem.SET)
246
+ self._result = self._set_maker(prev_state)
247
+
248
+ self._update_stack()
249
+ continue
250
+
251
+ if char == ']':
252
+ self._match()
253
+ self._update_stack()
254
+ stack_item, prev_state = self._stack.pop()
255
+ self._result = self._vector_maker(tuple(prev_state))
256
+ self._update_stack()
257
+ continue
258
+
259
+ if char == ')':
260
+ self._match()
261
+ self._update_stack()
262
+ stack_item, prev_state = self._stack.pop()
263
+ self._result = self._list_maker(prev_state)
264
+ self._update_stack()
265
+ continue
266
+
267
+ if char == '[':
268
+ self._match()
269
+ self._update_stack()
270
+ self._stack.append((ListParser._StackItem.VECTOR, []))
271
+ continue
272
+
273
+ if char == '(':
274
+ self._match()
275
+ self._update_stack()
276
+ self._stack.append((ListParser._StackItem.LIST, []))
277
+ continue
278
+
279
+ state_plus_char = self._state + char
280
+ if state_plus_char == '#_':
281
+ self._stack.append((ListParser._StackItem.TAG, char))
282
+ self._result = self._UNDEFINED
283
+ self._state = ''
284
+ continue
285
+
286
+ if state_plus_char.endswith('#{'):
287
+ self._state = self._state[:-1] # Remove the '#'
288
+ self._match()
289
+ self._update_stack()
290
+ self._stack.append((ListParser._StackItem.SET, []))
291
+ self._state = ''
292
+ continue
293
+
294
+ if char == '{':
295
+ self._match()
296
+ self._update_stack()
297
+ self._stack.append((ListParser._StackItem.MAP, [[], []]))
298
+ self._state = ''
299
+ continue
300
+
301
+ self._state += char
302
+ continue
303
+
304
+ elif self._mode == ListParser._ParseMode.STRING: # noqa
305
+ if char == '\\':
306
+ self._stack.append((self._mode, self._state))
307
+ self._mode = ListParser._ParseMode.ESCAPE
308
+ self._state = ''
309
+ continue
310
+
311
+ if char == '"':
312
+ self._mode = ListParser._ParseMode.IDLE
313
+ self._result = self._state
314
+ self._update_stack()
315
+ self._state = ''
316
+ continue
317
+
318
+ self._state += char
319
+
320
+ elif self._mode == ListParser._ParseMode.ESCAPE:
321
+ # TODO what should happen when escaping other char
322
+ escaped_char = self._STRING_ESCAPE_MAP.get(char, char)
323
+ stack_item, prev_state = self._stack.pop()
324
+ self._mode = check.isinstance(stack_item, ListParser._ParseMode)
325
+ self._state = prev_state + escaped_char
326
+
327
+ elif self._mode == ListParser._ParseMode.COMMENT:
328
+ if char == '\n':
329
+ self._mode = ListParser._ParseMode.IDLE
330
+
331
+ else:
332
+ raise RuntimeError(self._mode)
333
+
334
+ if i >= 0:
335
+ self._match()
336
+ self._update_stack()
337
+
338
+ check.state(not self._stack)
339
+
340
+ if self._result is not self._UNDEFINED:
341
+ values.append(self._result)
342
+ return values
343
+
344
+
345
+ #
346
+
347
+
348
+ def parse_list(src: str, **kwargs: ta.Any) -> list[ta.Any]:
349
+ """Parse an edn string and return the corresponding Python object."""
350
+
351
+ parser = ListParser(**kwargs)
352
+ return parser.parse(src)
353
+
354
+
355
+ def parse(src: str, **kwargs: ta.Any) -> ta.Any | None:
356
+ values = parse_list(src, **kwargs)
357
+ if not values:
358
+ return None
359
+ return check.single(values)
@@ -0,0 +1,162 @@
1
+ import dataclasses as dc
2
+ import typing as ta
3
+
4
+ from ... import check
5
+ from ... import lang
6
+ from ...lite.dataclasses import dataclass_cache_hash
7
+
8
+
9
+ ##
10
+
11
+
12
+ _DEBUG = __debug__
13
+ # _DEBUG = True
14
+
15
+
16
+ @dc.dataclass(frozen=True)
17
+ class Value(lang.Abstract, lang.Sealed):
18
+ pass
19
+
20
+
21
+ #
22
+
23
+
24
+ @dc.dataclass(frozen=True)
25
+ class Scalar(Value, lang.Abstract):
26
+ pass
27
+
28
+
29
+ @dataclass_cache_hash()
30
+ @dc.dataclass(frozen=True)
31
+ class Keyword(Scalar, lang.Final):
32
+ s: str
33
+
34
+ def __repr__(self) -> str:
35
+ return f'{self.__class__.__name__}({self.s!r})'
36
+
37
+ if _DEBUG:
38
+ def __post_init__(self) -> None:
39
+ check.isinstance(self.s, str)
40
+
41
+
42
+ @dataclass_cache_hash()
43
+ @dc.dataclass(frozen=True)
44
+ class Char(Scalar, lang.Final):
45
+ c: str
46
+
47
+ def __repr__(self) -> str:
48
+ return f'{self.__class__.__name__}({self.c!r})'
49
+
50
+ if _DEBUG:
51
+ def __post_init__(self) -> None:
52
+ check.isinstance(self.c, str)
53
+ check.equal(len(self.c), 1)
54
+
55
+
56
+ @dataclass_cache_hash()
57
+ @dc.dataclass(frozen=True)
58
+ class Symbol(Scalar, lang.Final):
59
+ n: str
60
+
61
+ def __repr__(self) -> str:
62
+ return f'{self.__class__.__name__}({self.n!r})'
63
+
64
+ if _DEBUG:
65
+ def __post_init__(self) -> None:
66
+ check.non_empty_str(self.n)
67
+
68
+
69
+ #
70
+
71
+
72
+ @dc.dataclass(frozen=True)
73
+ class Collection(Value, lang.Abstract):
74
+ pass
75
+
76
+
77
+ @dataclass_cache_hash()
78
+ @dc.dataclass(frozen=True)
79
+ class List(Collection, lang.Final):
80
+ items: ta.Sequence[ta.Any]
81
+
82
+ def __repr__(self) -> str:
83
+ return f'{self.__class__.__name__}({self.items!r})'
84
+
85
+ if _DEBUG:
86
+ def __post_init__(self) -> None:
87
+ check.isinstance(self.items, tuple)
88
+
89
+ @classmethod
90
+ def new(cls, items: ta.Iterable[ta.Any]) -> 'List':
91
+ return cls(tuple(items))
92
+
93
+
94
+ @dataclass_cache_hash()
95
+ @dc.dataclass(frozen=True)
96
+ class Vector(Collection, lang.Final):
97
+ items: ta.Sequence[ta.Any]
98
+
99
+ def __repr__(self) -> str:
100
+ return f'{self.__class__.__name__}({self.items!r})'
101
+
102
+ if _DEBUG:
103
+ def __post_init__(self) -> None:
104
+ check.isinstance(self.items, tuple)
105
+
106
+ @classmethod
107
+ def new(cls, items: ta.Iterable[ta.Any]) -> 'Vector':
108
+ return cls(tuple(items))
109
+
110
+
111
+ @dataclass_cache_hash()
112
+ @dc.dataclass(frozen=True)
113
+ class Set(Collection, lang.Final):
114
+ items: ta.Sequence[ta.Any]
115
+
116
+ def __repr__(self) -> str:
117
+ return f'{self.__class__.__name__}({self.items!r})'
118
+
119
+ if _DEBUG:
120
+ def __post_init__(self) -> None:
121
+ check.isinstance(self.items, tuple)
122
+
123
+ @classmethod
124
+ def new(cls, items: ta.Iterable[ta.Any]) -> 'Set':
125
+ return cls(tuple(items))
126
+
127
+
128
+ @dataclass_cache_hash()
129
+ @dc.dataclass(frozen=True)
130
+ class Map(Collection, lang.Final):
131
+ items: ta.Sequence[tuple[ta.Any, ta.Any]]
132
+
133
+ def __repr__(self) -> str:
134
+ return f'{self.__class__.__name__}({self.items!r})'
135
+
136
+ if _DEBUG:
137
+ def __post_init__(self) -> None:
138
+ check.isinstance(self.items, tuple)
139
+ for t in self.items:
140
+ check.isinstance(t, tuple)
141
+ check.equal(len(t), 2)
142
+
143
+ @classmethod
144
+ def new(cls, items: ta.Iterable[ta.Iterable[ta.Any]]) -> 'Map':
145
+ return cls(tuple((k, v) for k, v in items))
146
+
147
+
148
+ #
149
+
150
+
151
+ @dataclass_cache_hash()
152
+ @dc.dataclass(frozen=True)
153
+ class TaggedVal(Value, lang.Final):
154
+ t: str
155
+ v: ta.Any
156
+
157
+ def __repr__(self) -> str:
158
+ return f'{self.__class__.__name__}({self.t!r}, {self.v!r})'
159
+
160
+ if _DEBUG:
161
+ def __post_init__(self) -> None:
162
+ check.non_empty_str(self.t)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev305
3
+ Version: 0.0.0.dev306
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -40,7 +40,7 @@ Requires-Dist: aiomysql~=0.2; extra == "all"
40
40
  Requires-Dist: aiosqlite~=0.21; extra == "all"
41
41
  Requires-Dist: asyncpg~=0.30; extra == "all"
42
42
  Requires-Dist: apsw~=3.49; extra == "all"
43
- Requires-Dist: sqlean.py~=3.47; extra == "all"
43
+ Requires-Dist: sqlean.py~=3.49; extra == "all"
44
44
  Requires-Dist: duckdb~=1.2; extra == "all"
45
45
  Requires-Dist: markupsafe~=3.0; extra == "all"
46
46
  Requires-Dist: jinja2~=3.1; extra == "all"
@@ -88,7 +88,7 @@ Requires-Dist: aiomysql~=0.2; extra == "sqldrivers"
88
88
  Requires-Dist: aiosqlite~=0.21; extra == "sqldrivers"
89
89
  Requires-Dist: asyncpg~=0.30; extra == "sqldrivers"
90
90
  Requires-Dist: apsw~=3.49; extra == "sqldrivers"
91
- Requires-Dist: sqlean.py~=3.47; extra == "sqldrivers"
91
+ Requires-Dist: sqlean.py~=3.49; extra == "sqldrivers"
92
92
  Requires-Dist: duckdb~=1.2; extra == "sqldrivers"
93
93
  Provides-Extra: templates
94
94
  Requires-Dist: markupsafe~=3.0; extra == "templates"
@@ -1,5 +1,5 @@
1
- omlish/.manifests.json,sha256=pjGUyLHaoWpPqRP3jz2u1fC1qoRc2lvrEcpU_Ax2tdg,8253
2
- omlish/__about__.py,sha256=LvSNEgc-zfbkykExJmNhbtQkXdEXRqPSJufulYnCjfw,3478
1
+ omlish/.manifests.json,sha256=orgsRvtpHu8tdhaCvlP9v3P495OJopYYiHKjK68WtWg,8587
2
+ omlish/__about__.py,sha256=GhIrDhTYihc0evLBX7furXS9SiYupCmrYNe-MrlOL0w,3478
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -319,6 +319,11 @@ omlish/formats/props.py,sha256=auCv-Jx79KGlWfyG1-Qo0ou-Ex0W_mF3r_lDFdsVkWI,18920
319
319
  omlish/formats/repr.py,sha256=kYrNs4o-ji8nOdp6u_L3aMgBMWN1ZAZJSAWgQQfStSQ,414
320
320
  omlish/formats/xml.py,sha256=VJfqHR60dhAtjeG8WXFMozFqesTBSGvv264d67eDFXc,3514
321
321
  omlish/formats/yaml.py,sha256=jGPQlTE0vSV-p0O7TJRNlf6o1uq4gx8PrHZe1ApJ_o8,7386
322
+ omlish/formats/edn/LICENSE,sha256=EUHM_e21AO5QuuMYXhDE81wmeBxbxeEk_i8oToZhiJo,1078
323
+ omlish/formats/edn/__init__.py,sha256=JXHN8RlPAl-l2OnOQOQgYO8-f2zrYy-bGS2uaHiD9x0,183
324
+ omlish/formats/edn/codec.py,sha256=k6-Ra3P3Rlv6JA69-jPLI4nCe5XVes_QJbcsj5DYzMM,454
325
+ omlish/formats/edn/parsing.py,sha256=EtpFdeU1DPAh9pvPjEQSBwZJ9OESeonRkUFQdjmIh2Y,11212
326
+ omlish/formats/edn/values.py,sha256=m2mDkX0BP63-e81cBbZnB-S5zPzc-J-tYrFzycqL7AI,3488
322
327
  omlish/formats/ini/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
323
328
  omlish/formats/ini/codec.py,sha256=omuFg0kiDksv8rRlWd_v32ebzEcKlgmiPgGID3bRi2M,631
324
329
  omlish/formats/ini/sections.py,sha256=7wYyZdVTQbMPFpjQEACKJfAEPzUBrogINsrvFgxJoZ0,1015
@@ -847,9 +852,9 @@ omlish/typedvalues/holder.py,sha256=ZTnHiw-K38ciOBLEdwgrltr7Xp8jjEs_0Lp69DH-G-o,
847
852
  omlish/typedvalues/marshal.py,sha256=hWHRLcrGav7lvXJDtb9bNI0ickl4SKPQ6F4BbTpqw3A,4219
848
853
  omlish/typedvalues/reflect.py,sha256=Ih1YgU-srUjsvBn_P7C66f73_VCvcwqE3ffeBnZBgt4,674
849
854
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
850
- omlish-0.0.0.dev305.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
851
- omlish-0.0.0.dev305.dist-info/METADATA,sha256=xv6KDihpZe0TCjJOQAtfs6Yld4oOHnwCwhVuHNkBYR4,4416
852
- omlish-0.0.0.dev305.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
853
- omlish-0.0.0.dev305.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
854
- omlish-0.0.0.dev305.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
855
- omlish-0.0.0.dev305.dist-info/RECORD,,
855
+ omlish-0.0.0.dev306.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
856
+ omlish-0.0.0.dev306.dist-info/METADATA,sha256=GvMQ6j9pDWhBIlo-FffGTPzRwn6QSfgLdBRQ62RIshY,4416
857
+ omlish-0.0.0.dev306.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
858
+ omlish-0.0.0.dev306.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
859
+ omlish-0.0.0.dev306.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
860
+ omlish-0.0.0.dev306.dist-info/RECORD,,