omlish 0.0.0.dev62__py3-none-any.whl → 0.0.0.dev63__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/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev62'
2
- __revision__ = 'a5ef2d1548d1cdfb856b4a7ff99fe61080ab791e'
1
+ __version__ = '0.0.0.dev63'
2
+ __revision__ = '6de2b8280b36325b4e4b319adfe01b6a284bbdcc'
3
3
 
4
4
 
5
5
  #
omlish/argparse.py CHANGED
@@ -70,7 +70,7 @@ def arg(*args, **kwargs) -> Arg:
70
70
  #
71
71
 
72
72
 
73
- CommandFn = ta.Callable[[], None]
73
+ CommandFn = ta.Callable[[], int | None]
74
74
 
75
75
 
76
76
  @dc.dataclass(eq=False)
@@ -96,9 +96,9 @@ class Command:
96
96
  def __get__(self, instance, owner=None):
97
97
  if instance is None:
98
98
  return self
99
- return dc.replace(self, fn=self.fn.__get__(instance, owner))
99
+ return dc.replace(self, fn=self.fn.__get__(instance, owner)) # noqa
100
100
 
101
- def __call__(self, *args, **kwargs) -> None:
101
+ def __call__(self, *args, **kwargs) -> int | None:
102
102
  return self.fn(*args, **kwargs)
103
103
 
104
104
 
@@ -234,10 +234,10 @@ class Cli(metaclass=_CliMeta):
234
234
  def unknown_args(self) -> ta.Sequence[str]:
235
235
  return self._unknown_args
236
236
 
237
- def _run_cmd(self, cmd: Command) -> None:
238
- cmd.__get__(self, type(self))()
237
+ def _run_cmd(self, cmd: Command) -> int | None:
238
+ return cmd.__get__(self, type(self))()
239
239
 
240
- def __call__(self) -> None:
240
+ def __call__(self) -> int | None:
241
241
  cmd = getattr(self.args, '_cmd', None)
242
242
 
243
243
  if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
@@ -249,6 +249,9 @@ class Cli(metaclass=_CliMeta):
249
249
 
250
250
  if cmd is None:
251
251
  self.get_parser().print_help()
252
- return
252
+ return 0
253
253
 
254
- self._run_cmd(cmd)
254
+ return self._run_cmd(cmd)
255
+
256
+ def call_and_exit(self) -> ta.NoReturn:
257
+ sys.exit(rc if isinstance(rc := self(), int) else 0)
omlish/bootstrap/main.py CHANGED
@@ -83,7 +83,7 @@ def _add_arguments(parser: argparse.ArgumentParser) -> None:
83
83
  else:
84
84
  raise TypeError(fld)
85
85
 
86
- parser.add_argument(aname, action=_OrderedArgsAction, **kw)
86
+ parser.add_argument(aname.replace('_', '-'), action=_OrderedArgsAction, **kw)
87
87
 
88
88
 
89
89
  def _process_arguments(args: ta.Any) -> ta.Sequence[Bootstrap.Config]:
@@ -13,7 +13,7 @@ class IndexedSeq(ta.Sequence[T]):
13
13
  super().__init__()
14
14
 
15
15
  self._lst = list(it)
16
- self._idxs = (IdentityKeyDict if identity else dict)(map(reversed, enumerate(self._lst)))
16
+ self._idxs: ta.Mapping[T, int] = (IdentityKeyDict if identity else dict)((e, i) for i, e in enumerate(self._lst)) # noqa
17
17
  if len(self._idxs) != len(self._lst):
18
18
  raise ValueError(f'{len(self._idxs)} != {len(self._lst)}')
19
19
 
@@ -47,7 +47,7 @@ class IndexedSetSeq(ta.Sequence[ta.AbstractSet[T]]):
47
47
  super().__init__()
48
48
 
49
49
  self._lst = [(IdentitySet if identity else set)(e) for e in it]
50
- self._idxs = (IdentityKeyDict if identity else dict)((e, i) for i, es in enumerate(self._lst) for e in es)
50
+ self._idxs: ta.Mapping[T, int] = (IdentityKeyDict if identity else dict)((e, i) for i, es in enumerate(self._lst) for e in es) # noqa
51
51
  if len(self._idxs) != sum(map(len, self._lst)):
52
52
  raise ValueError(f'{len(self._idxs)} != {sum(map(len, self._lst))}')
53
53
 
omlish/docker/__init__.py CHANGED
@@ -24,4 +24,6 @@ from .helpers import ( # noqa
24
24
  from .hub import ( # noqa
25
25
  HubRepoInfo,
26
26
  get_hub_repo_info,
27
+ select_latest_tag,
28
+ split_tag_suffix,
27
29
  )
omlish/docker/hub.py CHANGED
@@ -1,15 +1,79 @@
1
1
  import typing as ta
2
+ import urllib.error
2
3
  import urllib.request
3
4
 
5
+ from .. import check
4
6
  from .. import dataclasses as dc
5
7
  from ..formats import json
6
8
 
7
9
 
10
+ ##
11
+
12
+
13
+ def _tag_sort_key(s: str) -> tuple:
14
+ l = []
15
+ for p in s.split('.'):
16
+ v: ta.Any
17
+ try:
18
+ v = int(p)
19
+ except ValueError:
20
+ v = s
21
+ l.append((not isinstance(v, int), v))
22
+ return tuple(l)
23
+
24
+
25
+ DEFAULT_TAG_SUFFIX_DELIM = '-+'
26
+
27
+
28
+ def split_tag_suffix(
29
+ tag: str,
30
+ suffix_delim: ta.Iterable[str] = DEFAULT_TAG_SUFFIX_DELIM,
31
+ ) -> tuple[str, str | None]:
32
+ for d in suffix_delim:
33
+ if d in tag:
34
+ p, _, s = tag.partition(d)
35
+ return p, s
36
+ return tag, None
37
+
38
+
39
+ def select_latest_tag(
40
+ tags: ta.Iterable[str],
41
+ *,
42
+ base: str | None = None,
43
+ suffix: str | None = None,
44
+ suffix_delim: ta.Iterable[str] = '-+',
45
+ ) -> str:
46
+ check.not_isinstance(tags, str)
47
+
48
+ tags_by_sfx: dict[str | None, set[tuple[tuple, str]]] = {}
49
+ for t in tags:
50
+ p, s = split_tag_suffix(t, suffix_delim)
51
+ tags_by_sfx.setdefault(s, set()).add((_tag_sort_key(p), t))
52
+
53
+ if base is not None:
54
+ bp, bs = split_tag_suffix(base, suffix_delim)
55
+ if suffix is None:
56
+ suffix = bs
57
+ base_key = _tag_sort_key(bp)
58
+ else:
59
+ base_key = None
60
+
61
+ sl = sorted(tags_by_sfx[suffix])
62
+
63
+ if base_key is not None:
64
+ sl = [(k, t) for k, t in sl if k[0] == base_key[0]]
65
+
66
+ return sl[-1][1]
67
+
68
+
69
+ ##
70
+
71
+
8
72
  @dc.dataclass(frozen=True)
9
73
  class HubRepoInfo:
10
74
  repo: str
11
- tags: ta.Mapping[str, ta.Any]
12
- latest_manifests: ta.Mapping[str, ta.Any]
75
+ tags: ta.Sequence[str]
76
+ manifests: ta.Mapping[str, ta.Mapping[str, ta.Any]]
13
77
 
14
78
 
15
79
  def get_hub_repo_info(
@@ -17,7 +81,9 @@ def get_hub_repo_info(
17
81
  *,
18
82
  auth_url: str = 'https://auth.docker.io/',
19
83
  api_url: str = 'https://registry-1.docker.io/v2/',
20
- ) -> HubRepoInfo:
84
+ tags: ta.Iterable[str] | None = None,
85
+ handled_codes: ta.Container[int] | None = (401, 404),
86
+ ) -> HubRepoInfo | None:
21
87
  """
22
88
  https://stackoverflow.com/a/39376254
23
89
 
@@ -36,10 +102,19 @@ def get_hub_repo_info(
36
102
  -s "https://registry-1.docker.io/v2/${repo}/manifests/latest" \
37
103
  | jq .
38
104
  """
105
+ if tags is not None:
106
+ check.not_isinstance(tags, str)
107
+ else:
108
+ tags = []
39
109
 
40
110
  auth_url = auth_url.rstrip('/')
41
111
  api_url = api_url.rstrip('/')
42
112
 
113
+ if '/' not in repo:
114
+ repo = '_/' + repo
115
+ if repo.startswith('_/'):
116
+ repo = 'library' + repo[1:]
117
+
43
118
  #
44
119
 
45
120
  def req_json(url: str, **kwargs: ta.Any) -> ta.Any:
@@ -55,21 +130,32 @@ def get_hub_repo_info(
55
130
 
56
131
  #
57
132
 
58
- tags_dct = req_json(
59
- f'{api_url}/{repo}/tags/list',
60
- headers=req_hdrs,
61
- )
62
-
63
- latest_mani_dct = req_json(
64
- f'{api_url}/{repo}/manifests/latest',
65
- headers={
66
- **req_hdrs,
67
- 'Accept': 'application/vnd.docker.distribution.manifest.v2+json',
68
- },
69
- )
133
+ try:
134
+ tags_resp = req_json(
135
+ f'{api_url}/{repo}/tags/list',
136
+ headers=req_hdrs,
137
+ )
138
+ except urllib.error.HTTPError as ue:
139
+ if ue.code in (handled_codes or ()):
140
+ return None
141
+ else:
142
+ raise
143
+
144
+ tags_dct = tags_resp.get('tags', {})
145
+
146
+ manis = {}
147
+ for tag in tags:
148
+ mani = req_json(
149
+ f'{api_url}/{repo}/manifests/latest',
150
+ headers={
151
+ **req_hdrs,
152
+ 'Accept': 'application/vnd.docker.distribution.manifest.v2+json',
153
+ },
154
+ )
155
+ manis[tag] = mani
70
156
 
71
157
  return HubRepoInfo(
72
158
  repo,
73
159
  tags_dct,
74
- latest_mani_dct,
160
+ manis,
75
161
  )
omlish/formats/yaml.py CHANGED
@@ -225,6 +225,14 @@ def load_all(stream, Loader): # noqa
225
225
  yield loader.get_data()
226
226
 
227
227
 
228
+ def safe_load(stream): # noqa
229
+ return load(stream, yaml.SafeLoader)
230
+
231
+
232
+ def safe_load_all(stream): # noqa # noqa
233
+ return load_all(stream, yaml.SafeLoader)
234
+
235
+
228
236
  def full_load(stream): # noqa
229
237
  return load(stream, yaml.FullLoader)
230
238
 
@@ -97,15 +97,15 @@ def update_wrapper(
97
97
  assigned: ta.Iterable[str] = functools.WRAPPER_ASSIGNMENTS,
98
98
  updated: ta.Iterable[str] = functools.WRAPPER_UPDATES,
99
99
  *,
100
- filter: ta.Iterable[str] | None = None, # noqa
100
+ exclude: ta.Iterable[str] | None = None,
101
101
  getattr: ta.Callable = getattr, # noqa
102
102
  setattr: ta.Callable = setattr, # noqa
103
103
  ) -> T:
104
- if filter:
105
- if isinstance(filter, str):
106
- filter = [filter] # noqa
107
- assigned = tuple(a for a in assigned if a not in filter)
108
- updated = tuple(a for a in updated if a not in filter)
104
+ if exclude:
105
+ if isinstance(exclude, str):
106
+ exclude = [exclude] # noqa
107
+ assigned = tuple(a for a in assigned if a not in exclude)
108
+ updated = tuple(a for a in updated if a not in exclude)
109
109
 
110
110
  for attr in assigned:
111
111
  try:
@@ -135,7 +135,7 @@ class _decorator_descriptor: # noqa
135
135
  if not _DECORATOR_HANDLES_UNBOUND_METHODS:
136
136
  def __init__(self, wrapper, fn):
137
137
  self._wrapper, self._fn = wrapper, fn
138
- update_wrapper(self, fn, filter='__dict__')
138
+ update_wrapper(self, fn, exclude='__dict__')
139
139
 
140
140
  def __get__(self, instance, owner=None):
141
141
  return functools.update_wrapper(functools.partial(self._wrapper, fn := self._fn.__get__(instance, owner)), fn) # noqa
@@ -144,7 +144,7 @@ class _decorator_descriptor: # noqa
144
144
  def __init__(self, wrapper, fn):
145
145
  self._wrapper, self._fn = wrapper, fn
146
146
  self._md = _has_method_descriptor(fn)
147
- update_wrapper(self, fn, filter='__dict__')
147
+ update_wrapper(self, fn, exclude='__dict__')
148
148
 
149
149
  def __get__(self, instance, owner=None):
150
150
  fn = self._fn.__get__(instance, owner)
@@ -174,7 +174,7 @@ class _decorator_descriptor: # noqa
174
174
  class _decorator: # noqa
175
175
  def __init__(self, wrapper):
176
176
  self._wrapper = wrapper
177
- update_wrapper(self, wrapper, filter='__dict__')
177
+ update_wrapper(self, wrapper, exclude='__dict__')
178
178
 
179
179
  def __repr__(self):
180
180
  return f'{self.__class__.__name__}<{self._wrapper}>'
omlish/lang/strings.py CHANGED
@@ -14,7 +14,7 @@ def prefix_delimited(s: StrOrBytesT, p: StrOrBytesT, d: StrOrBytesT) -> StrOrByt
14
14
 
15
15
 
16
16
  def prefix_lines(s: StrOrBytesT, p: StrOrBytesT) -> StrOrBytesT:
17
- return prefix_delimited(s, p, '\n' if isinstance(s, str) else b'\n')
17
+ return prefix_delimited(s, p, '\n' if isinstance(s, str) else b'\n') # type: ignore
18
18
 
19
19
 
20
20
  def indent_lines(s: StrOrBytesT, num: StrOrBytesT) -> StrOrBytesT:
omlish/lite/marshal.py CHANGED
@@ -246,29 +246,30 @@ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
246
246
 
247
247
 
248
248
  def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
249
- if isinstance(ty, type) and abc.ABC in ty.__bases__:
250
- impls = [ # type: ignore
251
- PolymorphicObjMarshaler.Impl(
252
- ity,
253
- ity.__qualname__,
254
- get_obj_marshaler(ity),
249
+ if isinstance(ty, type):
250
+ if abc.ABC in ty.__bases__:
251
+ impls = [ # type: ignore
252
+ PolymorphicObjMarshaler.Impl(
253
+ ity,
254
+ ity.__qualname__,
255
+ get_obj_marshaler(ity),
256
+ )
257
+ for ity in deep_subclasses(ty)
258
+ if abc.ABC not in ity.__bases__
259
+ ]
260
+ return PolymorphicObjMarshaler(
261
+ {i.ty: i for i in impls},
262
+ {i.tag: i for i in impls},
263
+ )
264
+
265
+ if issubclass(ty, enum.Enum):
266
+ return EnumObjMarshaler(ty)
267
+
268
+ if dc.is_dataclass(ty):
269
+ return DataclassObjMarshaler(
270
+ ty,
271
+ {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
255
272
  )
256
- for ity in deep_subclasses(ty)
257
- if abc.ABC not in ity.__bases__
258
- ]
259
- return PolymorphicObjMarshaler(
260
- {i.ty: i for i in impls},
261
- {i.tag: i for i in impls},
262
- )
263
-
264
- if isinstance(ty, type) and issubclass(ty, enum.Enum):
265
- return EnumObjMarshaler(ty)
266
-
267
- if dc.is_dataclass(ty):
268
- return DataclassObjMarshaler(
269
- ty,
270
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
271
- )
272
273
 
273
274
  if is_generic_alias(ty):
274
275
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev62
3
+ Version: 0.0.0.dev63
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,7 +1,7 @@
1
1
  omlish/.manifests.json,sha256=jvyoQ7x8UJ9lpRgkh7eElwJ8qnzyG5aUGameT9Yk8GM,1419
2
- omlish/__about__.py,sha256=u-gRUFmrAMM8C-1-u6UfjGvA_1qc3iVQiZLYnMGHQxg,3420
2
+ omlish/__about__.py,sha256=qlJrMz3s8VM_C0-4usZE5Jgx7f83IqPBmrc1ird0yoY,3420
3
3
  omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- omlish/argparse.py,sha256=Vr70_85EVLJLgEkRtwOr264tMRtqtlN7ncFfXRUk5aM,6914
4
+ omlish/argparse.py,sha256=XLrLFCLNY1RfbiXIAELkzHK-vUPum_9dyylEdJi9Pog,7068
5
5
  omlish/c3.py,sha256=4vogWgwPb8TbNS2KkZxpoWbwjj7MuHG2lQG-hdtkvjI,8062
6
6
  omlish/cached.py,sha256=UAizxlH4eMWHPzQtmItmyE6FEpFEUFzIkxaO2BHWZ5s,196
7
7
  omlish/check.py,sha256=fgWiBoHvqZlE8tjaxK7OMW4J8z3_rEGRENTka3EohbI,10378
@@ -91,7 +91,7 @@ omlish/bootstrap/__main__.py,sha256=4jCwsaogp0FrJjJZ85hzF4-WqluPeheHbfeoKynKvNs,
91
91
  omlish/bootstrap/base.py,sha256=d8hqn4hp1XMMi5PgcJBQXPKmW47epu8CxBlqDZiRZb4,1073
92
92
  omlish/bootstrap/diag.py,sha256=LADLhusbJ1tKxVD8-gmia1HShX1VeszRO1OApIQhSpI,5507
93
93
  omlish/bootstrap/harness.py,sha256=VW8YP-yENGyXIuJ8GL_xintArF13nafwpz-iAghPt34,1967
94
- omlish/bootstrap/main.py,sha256=ripSWAlYz3LVyv6S_Js9MWYO3QNKgBSaFQv3gqGjuRM,5885
94
+ omlish/bootstrap/main.py,sha256=yZhOHDDlj4xB5a89dRdT8z58FsqqnpoBg1-tvY2CJe4,5903
95
95
  omlish/bootstrap/marshal.py,sha256=ZxdAeMNd2qXRZ1HUK89HmEhz8tqlS9OduW34QBscKw0,516
96
96
  omlish/bootstrap/sys.py,sha256=i6veZeE83wO0HTl9b6ykj_pEN05fqu0enoAv4sw5Ayc,8742
97
97
  omlish/collections/__init__.py,sha256=tGUzvS_ZjiqALsLRy7JX3h4KZRQX2CmtdAfTRD7UwMk,1677
@@ -101,7 +101,7 @@ omlish/collections/coerce.py,sha256=o11AMrUiyoadd8WkdqeKPIpXf2xd0LyylzNCyJivCLU,
101
101
  omlish/collections/exceptions.py,sha256=shcS-NCnEUudF8qC_SmO2TQyjivKlS4TDjaz_faqQ0c,44
102
102
  omlish/collections/frozen.py,sha256=DGxemj_pVID85tSBm-Wns_x4ov0wOEIT6X5bVgJtmkA,4152
103
103
  omlish/collections/identity.py,sha256=jhEpC8tnfh3Sg-MJff1Fp9eMydt150wits_UeVdctUk,2723
104
- omlish/collections/indexed.py,sha256=YHs_q0GALisXPKKMgeDQxZ6hMzYndqDL3m3ag8cnzH0,2143
104
+ omlish/collections/indexed.py,sha256=tFQsIWH4k9QqsF5VB7DsIVNsRThiQNx-ooRF36X_PnU,2203
105
105
  omlish/collections/mappings.py,sha256=eEifLZez-BWunTuj6974bGxBFfNRODZpu6Oa7_2ME94,3190
106
106
  omlish/collections/ordered.py,sha256=RzEC3fHvrDeJQSWThVDNYQKke263Vje1II5YwtDwT1Q,2335
107
107
  omlish/collections/persistent.py,sha256=KG471s0bhhReQrjlmX0xaN9HeAIcrtT264ddZCxsExo,875
@@ -168,16 +168,16 @@ omlish/dispatch/_dispatch3.py,sha256=Vnu5DfoPWFJLodudBqoZBXGTi2wYk-Az56MXJgdQvwc
168
168
  omlish/dispatch/dispatch.py,sha256=8XQiLVoAq4u2oO0DnDSXQB9Q5qDk569l4CIFBqwDSyc,3847
169
169
  omlish/dispatch/functions.py,sha256=S8ElsLi6DKxTdtFGigWaF0vAquwy2sK-3f4iRLaYq70,1522
170
170
  omlish/dispatch/methods.py,sha256=XHjwwC9Gn4iDWxbyLAcbdSwRgVaq-8Bnn5cAwf5oZdA,5403
171
- omlish/docker/__init__.py,sha256=LGL5ByHrd7EaQnIDO6eLQvovDamngUiTfnpThV_4-MA,437
171
+ omlish/docker/__init__.py,sha256=dmda-4zBo0UM_CMws_1MOwtyObdF79LB0HF5IT3sDVk,482
172
172
  omlish/docker/cli.py,sha256=gtb9kitVfGnd4cr587NsVVk8D5Ok5y5SAsqD_SwGrSA,2565
173
173
  omlish/docker/compose.py,sha256=4drmnGQzbkOFJ9B6XSg9rnXkJeZz1ETmdcMe1PE790U,1237
174
174
  omlish/docker/helpers.py,sha256=j2eZIqIUpy34ZmoGyIzsYuKx9HeewwYBfrGNC99EFYk,928
175
- omlish/docker/hub.py,sha256=YcDYOi6t1FA2Sp0RVrmZ9cBXbzFWQ8wTps3wOskA-K0,1955
175
+ omlish/docker/hub.py,sha256=7LIuJGdA-N1Y1dmo50ynKM1KUTcnQM_5XbtPbdT_QLU,3940
176
176
  omlish/docker/manifests.py,sha256=LR4FpOGNUT3bZQ-gTjB6r_-1C3YiG30QvevZjrsVUQM,7068
177
177
  omlish/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
178
  omlish/formats/dotenv.py,sha256=UjZl3gac-0U24sDjCCGMcCqO1UCWG2Zs8PZ4JdAg2YE,17348
179
179
  omlish/formats/props.py,sha256=JwFJbKblqzqnzXf7YKFzQSDfcAXzkKsfoYvad6FPy98,18945
180
- omlish/formats/yaml.py,sha256=R3NTkjomsIfjsUNmSf_bOaCUIID3JTyHJHsliQDSYQo,6688
180
+ omlish/formats/yaml.py,sha256=DSJXUq9yanfxdS6ufNTyBHMtIZO57LRnJj4w9fLY1aM,6852
181
181
  omlish/formats/json/__init__.py,sha256=moSR67Qkju2eYb_qVDtaivepe44mxAnYuC8OCSbtETg,298
182
182
  omlish/formats/json/__main__.py,sha256=1wxxKZVkj_u7HCcewwMIbGuZj_Wph95yrUbm474Op9M,188
183
183
  omlish/formats/json/cli.py,sha256=4zftNijlIOnGUHYn5J1s4yRDRM1K4udBzS3Kh8R2vNc,3374
@@ -242,7 +242,7 @@ omlish/lang/clsdct.py,sha256=AjtIWLlx2E6D5rC97zQ3Lwq2SOMkbg08pdO_AxpzEHI,1744
242
242
  omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
243
243
  omlish/lang/contextmanagers.py,sha256=NEwaTLQMfhKawD5x_0HgI2RpeLXbMa5r9NqWqfDnUXI,10408
244
244
  omlish/lang/datetimes.py,sha256=ehI_DhQRM-bDxAavnp470XcekbbXc4Gdw9y1KpHDJT0,223
245
- omlish/lang/descriptors.py,sha256=tszC_fMICqCz1cUXejJ4beWzt6DlIBulknJFRkSTZp4,6615
245
+ omlish/lang/descriptors.py,sha256=RRBbkMgTzg82fFFE4D0muqobpM-ZZaOta6yB1lpX3s8,6617
246
246
  omlish/lang/exceptions.py,sha256=qJBo3NU1mOWWm-NhQUHCY5feYXR3arZVyEHinLsmRH4,47
247
247
  omlish/lang/functions.py,sha256=kkPfcdocg-OmyN7skIqrFxNvqAv89Zc_kXKYAN8vw8g,3895
248
248
  omlish/lang/imports.py,sha256=04ugFC8NI5sbL7NH4V0r0q_nFsP_AMkHLz697CVkMtQ,6274
@@ -251,7 +251,7 @@ omlish/lang/maybes.py,sha256=NYHZDjqDtwPMheDrj2VtUVujxRPf8Qpgk4ZlZCTvBZc,3492
251
251
  omlish/lang/objects.py,sha256=PJXGm-WgC7vpWzaXGwofk48V2XZNaQLje60K1ariwvQ,4454
252
252
  omlish/lang/resolving.py,sha256=OuN2mDTPNyBUbcrswtvFKtj4xgH4H4WglgqSKv3MTy0,1606
253
253
  omlish/lang/resources.py,sha256=-NmVTrSMKFZ6smVfOMz46ekZYVGgYh8cPooxQlFpG6s,2135
254
- omlish/lang/strings.py,sha256=LWgUy9WghUyV0zmZ1c3HZjEfekLlNPy7Jl6J1Z5vzp0,3882
254
+ omlish/lang/strings.py,sha256=BsciSYnckD4vGtC6kmtnugR9IN6CIHdcjO4nZu-pSAw,3898
255
255
  omlish/lang/sys.py,sha256=UoZz_PJYVKLQAKqYxxn-LHz1okK_38I__maZgnXMcxU,406
256
256
  omlish/lang/timeouts.py,sha256=vECdWYhc_IZgcal1Ng1Y42wf2FV3KAx-i8As-MgGHIQ,1186
257
257
  omlish/lang/typing.py,sha256=lJ2NGe4Pmb61I0Tx4A_rOqXNFTws1XHOzafg2knRUio,4155
@@ -274,7 +274,7 @@ omlish/lite/check.py,sha256=B0VnyBSWI5qipidkwnU-BP43S9E-UOgp4WUM17pVpHc,750
274
274
  omlish/lite/contextmanagers.py,sha256=HnQJiyrOmSvTL22XRJrFl5CLpCyHD9fsntEUAr9G-60,427
275
275
  omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
276
276
  omlish/lite/logs.py,sha256=vkFkSX0Izb2P-NNMqqNLSec0BzeLOtHoQWgdXwQuDPU,6007
277
- omlish/lite/marshal.py,sha256=u6jYUN_AndvI6__HJBvSw5ElHWC0CfHqgiDS28Vpqjg,8593
277
+ omlish/lite/marshal.py,sha256=kZtfIiFfmxEi8ZKne3fT0R8g8kLmJ-Q5nq4kOvwhiqk,8656
278
278
  omlish/lite/reflect.py,sha256=9QYJwdINraq1JNMEgvoqeSlVvRRgOXpxAkpgX8EgRXc,1307
279
279
  omlish/lite/runtime.py,sha256=VUhmNQvwf8QzkWSKj4Q0ReieJA_PzHaJNRBivfTseow,452
280
280
  omlish/lite/secrets.py,sha256=3Mz3V2jf__XU9qNHcH56sBSw95L3U2UPL24bjvobG0c,816
@@ -408,9 +408,9 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
408
408
  omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
409
409
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
410
410
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
411
- omlish-0.0.0.dev62.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
412
- omlish-0.0.0.dev62.dist-info/METADATA,sha256=mt0fT8Bk_wKy64eUKY_AYPNxHg-yruiGNd2EYcnYUPw,4167
413
- omlish-0.0.0.dev62.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
414
- omlish-0.0.0.dev62.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
415
- omlish-0.0.0.dev62.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
416
- omlish-0.0.0.dev62.dist-info/RECORD,,
411
+ omlish-0.0.0.dev63.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
412
+ omlish-0.0.0.dev63.dist-info/METADATA,sha256=3QDOoC7dBsLktT4vePuK9dx8FjSwpxlZnE27yP_qQ8c,4167
413
+ omlish-0.0.0.dev63.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
414
+ omlish-0.0.0.dev63.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
415
+ omlish-0.0.0.dev63.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
416
+ omlish-0.0.0.dev63.dist-info/RECORD,,