omlish 0.0.0.dev55__py3-none-any.whl → 0.0.0.dev57__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
@@ -35,6 +35,18 @@
35
35
  }
36
36
  }
37
37
  },
38
+ {
39
+ "module": ".formats.json.__main__",
40
+ "attr": "_CLI_MODULE",
41
+ "file": "omlish/formats/json/__main__.py",
42
+ "line": 1,
43
+ "value": {
44
+ "$omdev.cli.types.CliModule": {
45
+ "cmd_name": "json",
46
+ "mod_name": "omlish.formats.json.__main__"
47
+ }
48
+ }
49
+ },
38
50
  {
39
51
  "module": ".specs.jmespath.__main__",
40
52
  "attr": "_CLI_MODULE",
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev55'
2
- __revision__ = '6185da5f1914b76d0daffc87fd41272d70bf3806'
1
+ __version__ = '0.0.0.dev57'
2
+ __revision__ = '6bc82bd3fa6f9a7e33d9f3a69e8d3e1855aa6417'
3
3
 
4
4
 
5
5
  #
@@ -0,0 +1,19 @@
1
+ from .json import ( # noqa
2
+ COMPACT_KWARGS,
3
+ COMPACT_SEPARATORS,
4
+ PRETTY_INDENT,
5
+ PRETTY_KWARGS,
6
+ detect_encoding,
7
+ dump,
8
+ dump_compact,
9
+ dump_pretty,
10
+ dumps,
11
+ dumps_compact,
12
+ dumps_pretty,
13
+ load,
14
+ loads,
15
+ )
16
+
17
+ from .render import ( # noqa
18
+ JsonRenderer,
19
+ )
@@ -0,0 +1,11 @@
1
+ # @omlish-manifest
2
+ _CLI_MODULE = {'$omdev.cli.types.CliModule': {
3
+ 'cmd_name': 'json',
4
+ 'mod_name': __name__,
5
+ }}
6
+
7
+
8
+ if __name__ == '__main__':
9
+ from .cli import _main
10
+
11
+ _main()
File without changes
@@ -0,0 +1,72 @@
1
+ """
2
+ def loads(obj: str | bytes | bytearray | memoryview) -> ta.Any | oj.JSONDEcodeError
3
+ def dumps(obj: ta.Any, **DumpOpts) -> bytes
4
+ """
5
+ import dataclasses as dc
6
+ import typing as ta
7
+
8
+ from .... import lang
9
+
10
+
11
+ if ta.TYPE_CHECKING:
12
+ import orjson as oj
13
+ else:
14
+ oj = lang.proxy_import('orjson')
15
+
16
+
17
+ @dc.dataclass(frozen=True, kw_only=True)
18
+ class Options:
19
+ append_newline: bool = False # append \n to the output
20
+
21
+ indent_2: bool = False # pretty-print output with an indent of two spaces.
22
+
23
+ naive_utc: bool = False # serialize datetime.datetime objects without a tzinfo as UTC
24
+
25
+ non_str_keys: bool = False # serialize dict keys of type other than str
26
+
27
+ omit_microseconds: bool = False # do not serialize the microsecond field on datetime.datetime and datetime.time instances # noqa
28
+
29
+ passthrough_dataclass: bool = False # passthrough dataclasses.dataclass instances to default
30
+ passthrough_datetime: bool = False # passthrough datetime.datetime, datetime.date, and datetime.time instances to default # noqa
31
+ passthrough_subclass: bool = False # passthrough subclasses of builtin types to default
32
+
33
+ serialize_numpy: bool = False # serialize numpy.ndarray instances
34
+
35
+ sort_keys: bool = False # serialize dict keys in sorted order - the default is to serialize in an unspecified order
36
+
37
+ strict_integer: bool = False # enforce 53-bit limit on integers
38
+
39
+ utc_z: bool = False # serialize a UTC timezone on datetime.datetime instances as Z instead of +00:00
40
+
41
+ ##
42
+
43
+ def __int__(self) -> int:
44
+ return (
45
+ (oj.OPT_APPEND_NEWLINE if self.append_newline else 0) |
46
+
47
+ (oj.OPT_INDENT_2 if self.indent_2 else 0) |
48
+
49
+ (oj.OPT_NAIVE_UTC if self.naive_utc else 0) |
50
+
51
+ (oj.OPT_NON_STR_KEYS if self.non_str_keys else 0) |
52
+
53
+ (oj.OPT_OMIT_MICROSECONDS if self.omit_microseconds else 0) |
54
+
55
+ (oj.OPT_PASSTHROUGH_DATACLASS if self.passthrough_dataclass else 0) |
56
+ (oj.OPT_PASSTHROUGH_DATETIME if self.passthrough_datetime else 0) |
57
+ (oj.OPT_PASSTHROUGH_SUBCLASS if self.passthrough_subclass else 0) |
58
+
59
+ (oj.OPT_SERIALIZE_NUMPY if self.serialize_numpy else 0) |
60
+
61
+ (oj.OPT_SORT_KEYS if self.sort_keys else 0) |
62
+
63
+ (oj.OPT_STRICT_INTEGER if self.strict_integer else 0) |
64
+
65
+ (oj.OPT_UTC_Z if self.utc_z else 0)
66
+ )
67
+
68
+
69
+ @dc.dataclass(frozen=True, kw_only=True)
70
+ class DumpOpts:
71
+ default: ta.Callable[[ta.Any], ta.Any] | None = None
72
+ option: Options = Options()
@@ -0,0 +1,37 @@
1
+ """
2
+ load(fp: File, **LoadOpts) -> ta.Any | json.JSONDecodeError
3
+ loads(s: str | bytes | bytearray, **LoadOpts) -> ta.Any | json.JSONDecodeError
4
+ dump(obj: ta.Any, fp: File, **DumpOpts) -> None
5
+ dumps(obj: ta.Any, **DumpOpts) -> str
6
+ """
7
+ import dataclasses as dc
8
+ import json
9
+ import typing as ta
10
+
11
+
12
+ @dc.dataclass(frozen=True, kw_only=True)
13
+ class DumpOpts:
14
+ cls: type[json.JSONEncoder] | None = None
15
+ skipkeys: bool = False # dict keys that are not basic types will be skipped instead of raising a TypeError
16
+ ensure_ascii: bool = True # escape non-ASCII characters in JSON strings
17
+ check_circular: bool = True # if False a circular reference will result in an RecursionError
18
+ allow_nan: bool = True # use JS equivalents for out-of-range float values, otherwise raise ValueError
19
+ indent: int | None = None # item indent - 0 will insert only newlines, None is most compact
20
+ separators: tuple[str, str] | None = None # (item_separator, key_separator) - default (', ', ': ') if indent is None else (',', ': ') # noqa
21
+ default: ta.Callable[[ta.Any], ta.Any] | None = None # should return a serializable version of obj or raise TypeError # noqa
22
+ sort_keys: bool = False
23
+
24
+
25
+ @dc.dataclass(frozen=True, kw_only=True)
26
+ class LoadOpts:
27
+ cls: type[json.JSONDecoder] | None = None
28
+
29
+ parse_float: ta.Callable[[str], ta.Any] | None = None # by default this is equivalent to float(num_str)
30
+ parse_int: ta.Callable[[str], ta.Any] | None = None # by default this is equivalent to int(num_str)
31
+ parse_constant: ta.Callable[[str], ta.Any] | None = None # # called with one of the following strings: -Infinity, Infinity, NaN # noqa
32
+
33
+ # called with the result of any object literal decoded
34
+ object_hook: ta.Callable[[dict], ta.Any] | None = None
35
+
36
+ # called with the result of any object literal decoded with an ordered list of pairs, by default dict # noqa
37
+ object_pairs_hook: ta.Callable[[list[tuple[str, ta.Any]]], ta.Any] | None = None
@@ -0,0 +1,25 @@
1
+ """
2
+ load(fp: File) -> ta.Any | uj.JSONDecodeError
3
+ loads(s: str | bytes | bytearray) -> ta.Any | uj.JSONDecodeError
4
+ dump(obj: ta.Any, fp: File, **DumpOpts) -> None
5
+ dumps(obj: ta.Any, **DumpOpts) -> None
6
+ """
7
+ import dataclasses as dc
8
+ import typing as ta
9
+
10
+
11
+ @dc.dataclass(frozen=True, kw_only=True)
12
+ class DumpOpts:
13
+ """
14
+ https://github.com/ultrajson/ultrajson/blob/2e4aba339b0ab08f893590aaa989d12846afc5d6/python/objToJSON.c#L662
15
+ """
16
+
17
+ ensure_ascii: bool = True # limits output to ASCII and escapes all extended characters above 127.
18
+ encode_html_chars: bool = False # enables special encoding of "unsafe" HTML characters into safer Unicode sequences
19
+ escape_forward_slashes: bool = True # whether forward slashes (/) are escaped
20
+ indent: int = 0
21
+ sort_keys: bool = False
22
+ allow_nan: bool = True
23
+ reject_bytes: bool = True
24
+ default: ta.Callable[[ta.Any], ta.Any] | None = None # should return a serializable version of obj or raise TypeError # noqa
25
+ separators: tuple[str, str] | None = None
@@ -0,0 +1,141 @@
1
+ import argparse
2
+ import contextlib
3
+ import dataclasses as dc
4
+ import enum
5
+ import json
6
+ import subprocess
7
+ import sys
8
+ import typing as ta
9
+
10
+ from ... import lang
11
+ from ... import term
12
+ from .render import JsonRenderer
13
+
14
+
15
+ if ta.TYPE_CHECKING:
16
+ import tomllib
17
+
18
+ import yaml
19
+
20
+ from .. import dotenv
21
+ from .. import props
22
+
23
+ else:
24
+ tomllib = lang.proxy_import('tomllib')
25
+
26
+ yaml = lang.proxy_import('yaml')
27
+
28
+ dotenv = lang.proxy_import('..dotenv', __package__)
29
+ props = lang.proxy_import('..props', __package__)
30
+
31
+
32
+ def term_color(o: ta.Any, state: JsonRenderer.State) -> tuple[str, str]:
33
+ if state is JsonRenderer.State.KEY:
34
+ return term.SGR(term.SGRs.FG.BRIGHT_BLUE), term.SGR(term.SGRs.RESET)
35
+ elif isinstance(o, str):
36
+ return term.SGR(term.SGRs.FG.GREEN), term.SGR(term.SGRs.RESET)
37
+ else:
38
+ return '', ''
39
+
40
+
41
+ @dc.dataclass(frozen=True)
42
+ class Format:
43
+ names: ta.Sequence[str]
44
+ load: ta.Callable[[ta.TextIO], ta.Any]
45
+
46
+
47
+ class Formats(enum.Enum):
48
+ JSON = Format(['json'], json.load)
49
+ YAML = Format(['yaml', 'yml'], lambda f: yaml.safe_load(f))
50
+ TOML = Format(['toml'], lambda f: tomllib.loads(f.read()))
51
+ ENV = Format(['env', 'dotenv'], lambda f: dotenv.dotenv_values(stream=f))
52
+ PROPS = Format(['properties', 'props'], lambda f: dict(props.Properties().load(f.read())))
53
+
54
+
55
+ FORMATS_BY_NAME: ta.Mapping[str, Format] = {
56
+ n: f
57
+ for e in Formats
58
+ for f in [e.value]
59
+ for n in f.names
60
+ }
61
+
62
+
63
+ def _main() -> None:
64
+ parser = argparse.ArgumentParser()
65
+
66
+ parser.add_argument('file', nargs='?')
67
+ parser.add_argument('-f', '--format')
68
+ parser.add_argument('-z', '--compact', action='store_true')
69
+ parser.add_argument('-p', '--pretty', action='store_true')
70
+ parser.add_argument('-i', '--indent')
71
+ parser.add_argument('-s', '--sort-keys', action='store_true')
72
+ parser.add_argument('-c', '--color', action='store_true')
73
+ parser.add_argument('-l', '--less', action='store_true')
74
+ args = parser.parse_args()
75
+
76
+ separators = None
77
+ if args.compact:
78
+ separators = (',', ':')
79
+
80
+ indent = None
81
+ if args.pretty:
82
+ indent = 2
83
+ if args.indent:
84
+ try:
85
+ indent = int(args.indent)
86
+ except ValueError:
87
+ indent = args.indent
88
+
89
+ fmt_name = args.format
90
+ if fmt_name is None:
91
+ if args.file is not None:
92
+ ext = args.file.rpartition('.')[2]
93
+ if ext in FORMATS_BY_NAME:
94
+ fmt_name = ext
95
+ if fmt_name is None:
96
+ fmt_name = 'json'
97
+ fmt = FORMATS_BY_NAME[fmt_name]
98
+
99
+ with contextlib.ExitStack() as es:
100
+ if args.file is None:
101
+ in_file = sys.stdin
102
+ else:
103
+ in_file = es.enter_context(open(args.file))
104
+
105
+ data = fmt.load(in_file)
106
+
107
+ kw: dict[str, ta.Any] = dict(
108
+ indent=indent,
109
+ separators=separators,
110
+ sort_keys=args.sort_keys,
111
+ )
112
+
113
+ if args.color:
114
+ out = JsonRenderer.render_str(
115
+ data,
116
+ **kw,
117
+ style=term_color,
118
+ )
119
+
120
+ else:
121
+ out = json.dumps(
122
+ data,
123
+ **kw,
124
+ )
125
+
126
+ if args.less:
127
+ subprocess.run(
128
+ [
129
+ 'less',
130
+ *(['-R'] if args.color else []),
131
+ ],
132
+ input=out.encode(),
133
+ check=True,
134
+ )
135
+
136
+ else:
137
+ print(out)
138
+
139
+
140
+ if __name__ == '__main__':
141
+ _main()
@@ -7,17 +7,6 @@ import functools
7
7
  import json as _json
8
8
  import typing as ta
9
9
 
10
- from .. import lang
11
-
12
-
13
- if ta.TYPE_CHECKING:
14
- import orjson as _orjson
15
- import ujson as _ujson
16
-
17
- else:
18
- _orjson = lang.proxy_import('orjson')
19
- _ujson = lang.proxy_import('ujson')
20
-
21
10
 
22
11
  ##
23
12
 
@@ -0,0 +1,114 @@
1
+ import enum
2
+ import io
3
+ import json
4
+ import typing as ta
5
+
6
+
7
+ class JsonRenderer:
8
+ class State(enum.Enum):
9
+ VALUE = enum.auto()
10
+ KEY = enum.auto()
11
+
12
+ def __init__(
13
+ self,
14
+ out: ta.TextIO,
15
+ *,
16
+ indent: int | str | None = None,
17
+ separators: tuple[str, str] | None = None,
18
+ sort_keys: bool = False,
19
+ style: ta.Callable[[ta.Any, State], tuple[str, str]] | None = None,
20
+ ) -> None:
21
+ super().__init__()
22
+
23
+ self._out = out
24
+ if isinstance(indent, (str, int)):
25
+ self._indent = (' ' * indent) if isinstance(indent, int) else indent
26
+ self._endl = '\n'
27
+ if separators is None:
28
+ separators = (',', ': ')
29
+ elif indent is None:
30
+ self._indent = self._endl = ''
31
+ if separators is None:
32
+ separators = (', ', ': ')
33
+ else:
34
+ raise TypeError(indent)
35
+ self._comma, self._colon = separators
36
+ self._sort_keys = sort_keys
37
+ self._style = style
38
+
39
+ self._level = 0
40
+
41
+ _literals: ta.ClassVar[ta.Mapping[ta.Any, str]] = {
42
+ True: 'true',
43
+ False: 'false',
44
+ None: 'null',
45
+ }
46
+
47
+ def _write(self, s: str) -> None:
48
+ if s:
49
+ self._out.write(s)
50
+
51
+ def _write_indent(self) -> None:
52
+ if self._indent:
53
+ self._write(self._endl)
54
+ if self._level:
55
+ self._write(self._indent * self._level)
56
+
57
+ def _render(self, o: ta.Any, state: State = State.VALUE) -> None:
58
+ if self._style is not None:
59
+ pre, post = self._style(o, state)
60
+ self._write(pre)
61
+ else:
62
+ post = None
63
+
64
+ if o is None or isinstance(o, bool):
65
+ self._write(self._literals[o])
66
+
67
+ elif isinstance(o, (str, int, float)):
68
+ self._write(json.dumps(o))
69
+
70
+ elif isinstance(o, ta.Mapping):
71
+ self._write('{')
72
+ self._level += 1
73
+ items = list(o.items())
74
+ if self._sort_keys:
75
+ items.sort(key=lambda t: t[0])
76
+ for i, (k, v) in enumerate(items):
77
+ if i:
78
+ self._write(self._comma)
79
+ self._write_indent()
80
+ self._render(k, JsonRenderer.State.KEY)
81
+ self._write(self._colon)
82
+ self._render(v)
83
+ self._level -= 1
84
+ if o:
85
+ self._write_indent()
86
+ self._write('}')
87
+
88
+ elif isinstance(o, ta.Sequence):
89
+ self._write('[')
90
+ self._level += 1
91
+ for i, e in enumerate(o):
92
+ if i:
93
+ self._write(self._comma)
94
+ self._write_indent()
95
+ self._render(e)
96
+ self._level -= 1
97
+ if o:
98
+ self._write_indent()
99
+ self._write(']')
100
+
101
+ else:
102
+ raise TypeError(o)
103
+
104
+ if post:
105
+ self._write(post)
106
+
107
+ def render(self, o: ta.Any) -> None:
108
+ self._render(o)
109
+
110
+ @classmethod
111
+ def render_str(cls, o: ta.Any, **kwargs: ta.Any) -> str:
112
+ out = io.StringIO()
113
+ cls(out, **kwargs).render(o)
114
+ return out.getvalue()
omlish/formats/props.py CHANGED
@@ -508,7 +508,7 @@ class Properties(collections.abc.MutableMapping):
508
508
  source_data,
509
509
  encoding: str | None = 'iso-8859-1',
510
510
  metadoc: bool = False,
511
- ) -> None:
511
+ ) -> ta.Self:
512
512
  self.reset(metadoc)
513
513
 
514
514
  if isinstance(source_data, bytes):
@@ -522,6 +522,8 @@ class Properties(collections.abc.MutableMapping):
522
522
 
523
523
  self._parse()
524
524
 
525
+ return self
526
+
525
527
  def store(
526
528
  self,
527
529
  out_stream,
@@ -530,7 +532,7 @@ class Properties(collections.abc.MutableMapping):
530
532
  strict: bool = True,
531
533
  strip_meta: bool = True,
532
534
  timestamp: bool = True,
533
- ) -> None:
535
+ ) -> ta.Self:
534
536
  out_codec_info = codecs.lookup(encoding)
535
537
  wrapped_out_stream = out_codec_info.streamwriter(out_stream, _jbackslash_replace_codec_name)
536
538
  properties_escape_nonprinting = strict and out_codec_info == codecs.lookup('latin_1')
@@ -597,6 +599,8 @@ class Properties(collections.abc.MutableMapping):
597
599
  file=wrapped_out_stream,
598
600
  )
599
601
 
602
+ return self
603
+
600
604
  def list(self, out_stream=sys.stderr) -> None:
601
605
  print('-- listing properties --', file=out_stream)
602
606
  for key in self._properties:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev55
3
+ Version: 0.0.0.dev57
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
- omlish/.manifests.json,sha256=Xj-NnBpowZX7faAyhZ2j7g4fPFFw9Da7ITTC8AojNlM,1135
2
- omlish/__about__.py,sha256=86pwA2MtS7JWsIagoYPxrhXgpb3BzVvGI5w-JyrXhZM,3420
1
+ omlish/.manifests.json,sha256=wTGXwNmvtaKsDWtTwwj3Uib5Inaj8ZBn0MB69bE80X4,1419
2
+ omlish/__about__.py,sha256=TcVGEzTkX3fMqsIJaOXPCs013BBL_Tc4-lqbwNV4bgs,3420
3
3
  omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  omlish/argparse.py,sha256=Vr70_85EVLJLgEkRtwOr264tMRtqtlN7ncFfXRUk5aM,6914
5
5
  omlish/c3.py,sha256=4vogWgwPb8TbNS2KkZxpoWbwjj7MuHG2lQG-hdtkvjI,8062
@@ -116,9 +116,17 @@ omlish/docker/hub.py,sha256=YcDYOi6t1FA2Sp0RVrmZ9cBXbzFWQ8wTps3wOskA-K0,1955
116
116
  omlish/docker/manifests.py,sha256=LR4FpOGNUT3bZQ-gTjB6r_-1C3YiG30QvevZjrsVUQM,7068
117
117
  omlish/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
118
  omlish/formats/dotenv.py,sha256=UjZl3gac-0U24sDjCCGMcCqO1UCWG2Zs8PZ4JdAg2YE,17348
119
- omlish/formats/json.py,sha256=61XG6rveb3SSXmYrKvUmRdaVDyMD6C-7yVqXBBMu8t8,1017
120
- omlish/formats/props.py,sha256=diYjZDsG1s50ImJhkpeinMwjr8952nIVI-0gYhBIvCY,18897
119
+ omlish/formats/props.py,sha256=JwFJbKblqzqnzXf7YKFzQSDfcAXzkKsfoYvad6FPy98,18945
121
120
  omlish/formats/yaml.py,sha256=R3NTkjomsIfjsUNmSf_bOaCUIID3JTyHJHsliQDSYQo,6688
121
+ omlish/formats/json/__init__.py,sha256=moSR67Qkju2eYb_qVDtaivepe44mxAnYuC8OCSbtETg,298
122
+ omlish/formats/json/__main__.py,sha256=1wxxKZVkj_u7HCcewwMIbGuZj_Wph95yrUbm474Op9M,188
123
+ omlish/formats/json/cli.py,sha256=4zftNijlIOnGUHYn5J1s4yRDRM1K4udBzS3Kh8R2vNc,3374
124
+ omlish/formats/json/json.py,sha256=y8d8WWgzGZDTjzYc_xe9v4T0foXHI-UP7gjCwnHzUIA,828
125
+ omlish/formats/json/render.py,sha256=6edhSrxXWW3nzRfokp5qaldT0_YAj-HVEan_rErf-vo,3208
126
+ omlish/formats/json/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
+ omlish/formats/json/backends/orjson.py,sha256=GYZx0zgpxwkJbFh4EJLGa6VMoEK-Q6mf5tQp8aXqTDc,2526
128
+ omlish/formats/json/backends/std.py,sha256=00NdUFT9GeWL1EWbgKhWLboDBIuDxr7EiizPZXbRWrc,1973
129
+ omlish/formats/json/backends/ujson.py,sha256=m5-hlEQCMLhat3Hg_8QTyfMH-rSsQGJYdWRWoTWkfhM,1029
122
130
  omlish/graphs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
131
  omlish/graphs/dags.py,sha256=JpTGxt5rsK7hy5EUy9rNUlIeDStT9ri86m8xEKiHQLE,3063
124
132
  omlish/graphs/domination.py,sha256=45iTyn7mZWPJ1ANrqD96aPXqzEeyFpybMvvcVxo9XvQ,7592
@@ -339,9 +347,9 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
339
347
  omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
340
348
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
341
349
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
342
- omlish-0.0.0.dev55.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
343
- omlish-0.0.0.dev55.dist-info/METADATA,sha256=KETPIaUeC-qvI4B-ZMyZKQC6pNl-9-GHQdoNBC5Yc4w,4167
344
- omlish-0.0.0.dev55.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
345
- omlish-0.0.0.dev55.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
346
- omlish-0.0.0.dev55.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
347
- omlish-0.0.0.dev55.dist-info/RECORD,,
350
+ omlish-0.0.0.dev57.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
351
+ omlish-0.0.0.dev57.dist-info/METADATA,sha256=SSyQEUrMKl0Bkig1soCu8_V7T-AVM8weCHYyMkDp8bc,4167
352
+ omlish-0.0.0.dev57.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
353
+ omlish-0.0.0.dev57.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
354
+ omlish-0.0.0.dev57.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
355
+ omlish-0.0.0.dev57.dist-info/RECORD,,