omlish 0.0.0.dev400__py3-none-any.whl → 0.0.0.dev402__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.dev400'
2
- __revision__ = '4e9cb702d1d048bb8211070b471983d3b4d7bb6d'
1
+ __version__ = '0.0.0.dev402'
2
+ __revision__ = '923dbb60edd6e046587daf400ee931ae9ec619de'
3
3
 
4
4
 
5
5
  #
@@ -51,7 +51,7 @@ class Project(ProjectBase):
51
51
 
52
52
  'python-snappy ~= 0.7',
53
53
 
54
- 'zstandard ~= 0.23',
54
+ 'zstandard ~= 0.24',
55
55
 
56
56
  'brotli ~= 1.1',
57
57
  ],
omlish/codecs/registry.py CHANGED
@@ -102,10 +102,10 @@ def _install_standard_codecs(registry: CodecRegistry) -> None:
102
102
 
103
103
  @cached.function
104
104
  def _build_manifest_lazy_loaded_codecs() -> ta.Sequence[LazyLoadedCodec]:
105
- ldr = manifest_globals.MANIFEST_LOADER
106
- pkgs = {__package__.split('.')[0], *ldr.discover_pkgs()}
105
+ ldr = manifest_globals.GlobalManifestLoader.instance()
106
+ pkgs = {__package__.split('.')[0], *ldr.discover_packages()}
107
107
  mns = ldr.load(*pkgs, only=[LazyLoadedCodec])
108
- return [m.value for m in mns]
108
+ return [m.value() for m in mns]
109
109
 
110
110
 
111
111
  def _install_manifest_lazy_loaded_codecs(registry: CodecRegistry) -> None:
@@ -1,3 +1,4 @@
1
+ # fmt: off
1
2
  # ruff: noqa: I001
2
3
  from .. import lang as _lang
3
4
 
@@ -1,6 +1,7 @@
1
1
  """
2
2
  TODO:
3
3
  - AsyncExitStacked
4
+ - lol does double_check_setdefault need a CowDict in FT?
4
5
  """
5
6
  import abc
6
7
  import contextlib
@@ -1,6 +1,6 @@
1
1
  """
2
2
  TODO:
3
- - overhaul this - use pkgutil.walk_packages unless called needs non-importing (which this currently doesn't do anyway),
3
+ - overhaul this - use pkgutil.walk_packages unless caller needs non-importing (which this currently doesn't do anyway),
4
4
  and support namespace packages if they do.
5
5
  """
6
6
  import contextlib
@@ -1,4 +1,8 @@
1
+ # ruff: noqa: UP045
1
2
  # @omlish-lite
3
+ import threading
4
+ import typing as ta
5
+
2
6
  from ..lite.marshal import unmarshal_obj
3
7
  from .loading import ManifestLoader
4
8
 
@@ -6,6 +10,59 @@ from .loading import ManifestLoader
6
10
  ##
7
11
 
8
12
 
9
- MANIFEST_LOADER = ManifestLoader(
10
- cls_instantiator=lambda cls, **kwargs: unmarshal_obj(kwargs, cls),
11
- )
13
+ class GlobalManifestLoader:
14
+ def __new__(cls, *args, **kwargs): # noqa
15
+ raise TypeError
16
+
17
+ def __init_subclass__(cls, **kwargs): # noqa
18
+ raise TypeError
19
+
20
+ ##
21
+
22
+ _lock: ta.ClassVar[threading.RLock] = threading.RLock()
23
+
24
+ _instance: ta.ClassVar[ta.Optional[ManifestLoader]] = None
25
+
26
+ @classmethod
27
+ def instance(cls) -> ManifestLoader:
28
+ if (inst := cls._instance) is None:
29
+ with cls._lock:
30
+ if (inst := cls._instance) is None:
31
+ inst = cls._instance = ManifestLoader(**cls.default_kwargs())
32
+
33
+ return inst
34
+
35
+ @classmethod
36
+ def initialize(cls, **kwargs: ta.Any) -> ManifestLoader:
37
+ with cls._lock:
38
+ if cls._instance is not None:
39
+ raise Exception(f'{cls.__name__} already initialized')
40
+
41
+ inst = cls._instance = ManifestLoader(**kwargs)
42
+
43
+ return inst
44
+
45
+ ##
46
+
47
+ @classmethod
48
+ def default_value_instantiator(cls, obj_cls: type, **kwargs: ta.Any) -> ta.Any:
49
+ return unmarshal_obj(kwargs, obj_cls)
50
+
51
+ @classmethod
52
+ def default_kwargs(cls) -> ta.Mapping[str, ta.Any]:
53
+ return dict(
54
+ value_instantiator=cls.default_value_instantiator,
55
+ )
56
+
57
+ ##
58
+
59
+ @classmethod
60
+ def load(
61
+ cls,
62
+ *pkg_names: str,
63
+ only: ta.Optional[ta.Iterable[type]] = None,
64
+ ) -> ta.Sequence[ManifestLoader.LoadedManifest]:
65
+ return cls.instance().load(
66
+ *pkg_names,
67
+ only=only,
68
+ )
@@ -5,6 +5,11 @@ Should be kept somewhat lightweight - used in cli entrypoints.
5
5
 
6
6
  TODO:
7
7
  - persisted caching support - {pkg_name: manifests}
8
+ - real relative cls names - shouldn't need parent package names
9
+ - *require* loaded class names - special All sentinel for explicit all
10
+ - ! late instantiation !
11
+ - TypeMap style weak cache of issubclass queries
12
+ - wait.. lazily load the class for virtual subclass queries? xor support virtual bases?
8
13
  """
9
14
  import dataclasses as dc
10
15
  import importlib.machinery
@@ -22,34 +27,101 @@ from .types import Manifest
22
27
 
23
28
 
24
29
  class ManifestLoader:
30
+ class LoadedManifest:
31
+ def __init__(
32
+ self,
33
+ package: 'ManifestLoader.LoadedPackage',
34
+ manifest: Manifest,
35
+ ) -> None:
36
+ super().__init__()
37
+
38
+ self._package = package
39
+ self._manifest = manifest
40
+
41
+ @property
42
+ def package(self) -> 'ManifestLoader.LoadedPackage':
43
+ return self._package
44
+
45
+ @property
46
+ def manifest(self) -> Manifest:
47
+ return self._manifest
48
+
49
+ @property
50
+ def loader(self) -> 'ManifestLoader':
51
+ return self._package.loader
52
+
53
+ @property
54
+ def class_key(self) -> str:
55
+ [(cls_key, value_dct)] = self._manifest.value.items()
56
+ return cls_key
57
+
58
+ _value: ta.Any
59
+
60
+ def value(self) -> ta.Any:
61
+ try:
62
+ return self._value
63
+ except AttributeError:
64
+ pass
65
+
66
+ value = self.loader._instantiate_loaded_manifest(self) # noqa
67
+ self._value = value
68
+ return value
69
+
70
+ class LoadedPackage:
71
+ def __init__(
72
+ self,
73
+ loader: 'ManifestLoader',
74
+ name: str,
75
+ ) -> None:
76
+ super().__init__()
77
+
78
+ self._loader = loader
79
+ self._name = name
80
+
81
+ _manifests: ta.Sequence['ManifestLoader.LoadedManifest']
82
+
83
+ @property
84
+ def loader(self) -> 'ManifestLoader':
85
+ return self._loader
86
+
87
+ @property
88
+ def name(self) -> str:
89
+ return self._name
90
+
91
+ @property
92
+ def manifests(self) -> ta.Sequence['ManifestLoader.LoadedManifest']:
93
+ return self._manifests
94
+
25
95
  def __init__(
26
96
  self,
27
97
  *,
28
98
  module_remap: ta.Optional[ta.Mapping[str, str]] = None,
29
- cls_instantiator: ta.Optional[ta.Callable[..., ta.Any]] = None,
99
+ value_instantiator: ta.Optional[ta.Callable[..., ta.Any]] = None,
30
100
  ) -> None:
31
101
  super().__init__()
32
102
 
33
- self._cls_instantiator = cls_instantiator
103
+ self._value_instantiator = value_instantiator
104
+ self._module_remap = module_remap or {}
34
105
 
35
106
  self._lock = threading.RLock()
36
107
 
37
- self._module_remap = module_remap or {}
38
108
  self._module_reverse_remap = {v: k for k, v in self._module_remap.items()}
39
109
 
40
- self._cls_cache: ta.Dict[str, type] = {}
41
- self._raw_cache: ta.Dict[str, ta.Optional[ta.Sequence[Manifest]]] = {}
110
+ self._loaded_classes: ta.Dict[str, type] = {}
111
+ self._loaded_packages: ta.Dict[str, ta.Optional[ManifestLoader.LoadedPackage]] = {}
112
+
113
+ self._scanned_package_root_dirs: ta.Dict[str, ta.Sequence[str]] = {}
42
114
 
43
115
  #
44
116
 
45
117
  @classmethod
46
- def from_entry_point(
118
+ def kwargs_from_entry_point(
47
119
  cls,
48
120
  globals: ta.Mapping[str, ta.Any], # noqa
49
121
  *,
50
122
  module_remap: ta.Optional[ta.Mapping[str, str]] = None,
51
123
  **kwargs: ta.Any,
52
- ) -> 'ManifestLoader':
124
+ ) -> ta.Dict[str, ta.Any]:
53
125
  rm: ta.Dict[str, str] = {}
54
126
 
55
127
  if module_remap:
@@ -61,16 +133,11 @@ class ManifestLoader:
61
133
  if '__main__' not in rm and name == '__main__':
62
134
  rm[spec.name] = '__main__'
63
135
 
64
- return cls(module_remap=rm, **kwargs)
136
+ return dict(module_remap=rm, **kwargs)
65
137
 
66
138
  #
67
139
 
68
- def _load_cls(self, key: str) -> type:
69
- try:
70
- return self._cls_cache[key]
71
- except KeyError:
72
- pass
73
-
140
+ def _load_class_uncached(self, key: str) -> type:
74
141
  if not key.startswith('$'):
75
142
  raise Exception(f'Bad key: {key}')
76
143
 
@@ -89,16 +156,25 @@ class ManifestLoader:
89
156
  if not isinstance(cls, type):
90
157
  raise TypeError(cls)
91
158
 
92
- self._cls_cache[key] = cls
93
159
  return cls
94
160
 
95
- def load_cls(self, key: str) -> type:
161
+ def _load_class_locked(self, key: str) -> type:
162
+ try:
163
+ return self._loaded_classes[key]
164
+ except KeyError:
165
+ pass
166
+
167
+ cls = self._load_class_uncached(key)
168
+ self._loaded_classes[key] = cls
169
+ return cls
170
+
171
+ def _load_class(self, key: str) -> type:
96
172
  with self._lock:
97
- return self._load_cls(key)
173
+ return self._load_class_locked(key)
98
174
 
99
175
  #
100
176
 
101
- def _load_contents(self, obj: ta.Any, pkg_name: str) -> ta.Sequence[Manifest]:
177
+ def _deserialize_raw_manifests(self, obj: ta.Any, pkg_name: str) -> ta.Sequence[Manifest]:
102
178
  if not isinstance(obj, (list, tuple)):
103
179
  raise TypeError(obj)
104
180
 
@@ -119,13 +195,9 @@ class ManifestLoader:
119
195
 
120
196
  return lst
121
197
 
122
- def load_contents(self, obj: ta.Any, pkg_name: str) -> ta.Sequence[Manifest]:
123
- with self._lock:
124
- return self.load_contents(obj, pkg_name)
125
-
126
198
  #
127
199
 
128
- def _read_pkg_file_text(self, pkg_name: str, file_name: str) -> ta.Optional[str]:
200
+ def _read_package_file_text(self, pkg_name: str, file_name: str) -> ta.Optional[str]:
129
201
  # importlib.resources.files actually imports the package - to avoid this, if possible, the file is read straight
130
202
  # off the filesystem.
131
203
  spec = importlib.util.find_spec(pkg_name)
@@ -149,45 +221,72 @@ class ManifestLoader:
149
221
 
150
222
  MANIFESTS_FILE_NAME: ta.ClassVar[str] = '.manifests.json'
151
223
 
152
- def _load_raw(self, pkg_name: str) -> ta.Optional[ta.Sequence[Manifest]]:
153
- try:
154
- return self._raw_cache[pkg_name]
155
- except KeyError:
156
- pass
157
-
158
- src = self._read_pkg_file_text(pkg_name, self.MANIFESTS_FILE_NAME)
224
+ def _load_package_uncached(self, pkg_name: str) -> ta.Optional[LoadedPackage]:
225
+ src = self._read_package_file_text(pkg_name, self.MANIFESTS_FILE_NAME)
159
226
  if src is None:
160
- self._raw_cache[pkg_name] = None
161
227
  return None
162
228
 
163
229
  obj = json.loads(src)
164
230
  if not isinstance(obj, (list, tuple)):
165
231
  raise TypeError(obj)
166
232
 
167
- lst = self._load_contents(obj, pkg_name)
233
+ raw_lst = self._deserialize_raw_manifests(obj, pkg_name)
168
234
 
169
- self._raw_cache[pkg_name] = lst
170
- return lst
235
+ ld_pkg = ManifestLoader.LoadedPackage(self, pkg_name)
236
+
237
+ ld_man_lst: ta.List[ManifestLoader.LoadedManifest] = []
238
+ for raw in raw_lst:
239
+ ld_man = ManifestLoader.LoadedManifest(ld_pkg, raw)
240
+
241
+ ld_man_lst.append(ld_man)
242
+
243
+ ld_pkg._manifests = ld_man_lst # noqa
244
+
245
+ return ld_pkg
246
+
247
+ def _load_package_locked(self, pkg_name: str) -> ta.Optional[LoadedPackage]:
248
+ try:
249
+ return self._loaded_packages[pkg_name]
250
+ except KeyError:
251
+ pass
171
252
 
172
- def load_raw(self, pkg_name: str) -> ta.Optional[ta.Sequence[Manifest]]:
253
+ pkg = self._load_package_uncached(pkg_name)
254
+ self._loaded_packages[pkg_name] = pkg
255
+ return pkg
256
+
257
+ def load_package(self, pkg_name: str) -> ta.Optional[LoadedPackage]:
173
258
  with self._lock:
174
- return self._load_raw(pkg_name)
259
+ return self._load_package_locked(pkg_name)
175
260
 
176
261
  #
177
262
 
178
- def instantiate_cls(self, cls: type, **kwargs: ta.Any) -> ta.Any:
179
- if self._cls_instantiator is not None:
180
- return self._cls_instantiator(cls, **kwargs)
263
+ def _instantiate_value(self, cls: type, **kwargs: ta.Any) -> ta.Any:
264
+ if self._value_instantiator is not None:
265
+ return self._value_instantiator(cls, **kwargs)
181
266
  else:
182
267
  return cls(**kwargs)
183
268
 
269
+ def _instantiate_loaded_manifest(self, ld_man: LoadedManifest) -> ta.Any:
270
+ [(cls_key, value_dct)] = ld_man.manifest.value.items()
271
+ cls = self._load_class(cls_key)
272
+ value = self._instantiate_value(cls, **value_dct)
273
+ return value
274
+
275
+ #
276
+
277
+ # FIXME:
278
+ # class LOAD_ALL: # noqa
279
+ # def __new__(cls, *args, **kwargs): # noqa
280
+ # raise TypeError
184
281
  #
282
+ # def __init_subclass__(cls, **kwargs): # noqa
283
+ # raise TypeError
185
284
 
186
285
  def _load(
187
286
  self,
188
287
  *pkg_names: str,
189
288
  only: ta.Optional[ta.Iterable[type]] = None,
190
- ) -> ta.Sequence[Manifest]:
289
+ ) -> ta.Sequence[LoadedManifest]:
191
290
  only_keys: ta.Optional[ta.Set]
192
291
  if only is not None:
193
292
  only_keys = set()
@@ -200,18 +299,17 @@ class ManifestLoader:
200
299
  else:
201
300
  only_keys = None
202
301
 
203
- lst: ta.List[Manifest] = []
302
+ lst: ta.List[ManifestLoader.LoadedManifest] = []
204
303
  for pn in pkg_names:
205
- for manifest in (self.load_raw(pn) or []):
206
- [(key, value_dct)] = manifest.value.items()
207
- if only_keys is not None and key not in only_keys:
208
- continue
304
+ lp = self.load_package(pn)
305
+ if lp is None:
306
+ continue
209
307
 
210
- cls = self._load_cls(key)
211
- value = self.instantiate_cls(cls, **value_dct)
308
+ for m in lp.manifests:
309
+ if only_keys is not None and m.class_key not in only_keys:
310
+ continue
212
311
 
213
- manifest = dc.replace(manifest, value=value)
214
- lst.append(manifest)
312
+ lst.append(m)
215
313
 
216
314
  return lst
217
315
 
@@ -219,7 +317,7 @@ class ManifestLoader:
219
317
  self,
220
318
  *pkg_names: str,
221
319
  only: ta.Optional[ta.Iterable[type]] = None,
222
- ) -> ta.Sequence[Manifest]:
320
+ ) -> ta.Sequence[LoadedManifest]:
223
321
  with self._lock:
224
322
  return self._load(
225
323
  *pkg_names,
@@ -228,42 +326,82 @@ class ManifestLoader:
228
326
 
229
327
  #
230
328
 
231
- ENTRY_POINT_GROUP = 'omlish.manifests'
329
+ ENTRY_POINT_GROUP: ta.ClassVar[str] = 'omlish.manifests'
330
+
331
+ _discovered_packages: ta.ClassVar[ta.Optional[ta.Sequence[str]]] = None
332
+
333
+ @classmethod
334
+ def discover_packages(cls) -> ta.Sequence[str]:
335
+ if (x := cls._discovered_packages) is not None:
336
+ return x
232
337
 
233
- def discover_pkgs(self) -> ta.Sequence[str]:
234
338
  # This is a fat dep so do it late.
235
339
  from importlib import metadata as importlib_metadata # noqa
236
340
 
237
- return [
341
+ x = [
238
342
  ep.value
239
- for ep in importlib_metadata.entry_points(group=self.ENTRY_POINT_GROUP)
343
+ for ep in importlib_metadata.entry_points(group=cls.ENTRY_POINT_GROUP)
240
344
  ]
241
345
 
242
- def scan_pkg_root(self, root: str) -> ta.Sequence[str]:
346
+ cls._discovered_packages = x
347
+ return x
348
+
349
+ #
350
+
351
+ def _scan_package_root_dir_uncached(
352
+ self,
353
+ root_dir: str,
354
+ ) -> ta.Sequence[str]:
243
355
  pkgs: ta.List[str] = []
244
- for n in os.listdir(root):
245
- if os.path.isdir(p := os.path.join(root, n)) and os.path.exists(os.path.join(p, '__init__.py')):
356
+
357
+ for n in os.listdir(root_dir):
358
+ if (
359
+ os.path.isdir(p := os.path.join(root_dir, n)) and
360
+ os.path.exists(os.path.join(p, '__init__.py'))
361
+ ):
246
362
  pkgs.append(n)
363
+
247
364
  return pkgs
248
365
 
249
- def scan_or_discover_pkgs(
366
+ def _scan_package_root_dir_locked(
367
+ self,
368
+ root_dir: str,
369
+ ) -> ta.Sequence[str]:
370
+ try:
371
+ return self._scanned_package_root_dirs[root_dir]
372
+ except KeyError:
373
+ pass
374
+
375
+ ret = self._scan_package_root_dir_uncached(root_dir)
376
+ self._scanned_package_root_dirs[root_dir] = ret
377
+ return ret
378
+
379
+ def _scan_package_root_dir(
380
+ self,
381
+ root_dir: str,
382
+ ) -> ta.Sequence[str]:
383
+ with self._lock:
384
+ return self._scan_package_root_dir_locked(root_dir)
385
+
386
+ def scan_or_discover_packages(
250
387
  self,
251
388
  *,
252
- specified_roots: ta.Optional[ta.Sequence[str]] = None,
253
- fallback_root: ta.Optional[str] = None,
389
+ specified_root_dirs: ta.Optional[ta.Sequence[str]] = None,
390
+ fallback_root_dir: ta.Optional[str] = None,
254
391
  ) -> ta.Sequence[str]:
255
392
  pkgs: list[str] = []
256
393
 
257
- if specified_roots is not None:
258
- if isinstance(specified_roots, str):
259
- raise TypeError(specified_roots)
260
- for r in specified_roots:
261
- pkgs.extend(self.scan_pkg_root(r))
394
+ if specified_root_dirs is not None:
395
+ if isinstance(specified_root_dirs, str):
396
+ raise TypeError(specified_root_dirs)
397
+
398
+ for r in specified_root_dirs:
399
+ pkgs.extend(self._scan_package_root_dir(r))
262
400
 
263
401
  else:
264
- pkgs.extend(self.discover_pkgs())
402
+ pkgs.extend(self.discover_packages())
265
403
 
266
- if not pkgs and fallback_root is not None:
267
- pkgs.extend(self.scan_pkg_root(fallback_root))
404
+ if not pkgs and fallback_root_dir is not None:
405
+ pkgs.extend(self._scan_package_root_dir(fallback_root_dir))
268
406
 
269
407
  return pkgs
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev400
3
+ Version: 0.0.0.dev402
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -22,7 +22,7 @@ Requires-Dist: trio~=0.30; extra == "all"
22
22
  Requires-Dist: trio-asyncio~=0.15; extra == "all"
23
23
  Requires-Dist: lz4~=4.4; extra == "all"
24
24
  Requires-Dist: python-snappy~=0.7; extra == "all"
25
- Requires-Dist: zstandard~=0.23; extra == "all"
25
+ Requires-Dist: zstandard~=0.24; extra == "all"
26
26
  Requires-Dist: brotli~=1.1; extra == "all"
27
27
  Requires-Dist: asttokens~=3.0; extra == "all"
28
28
  Requires-Dist: executing~=2.2; extra == "all"
@@ -63,7 +63,7 @@ Requires-Dist: trio-asyncio~=0.15; extra == "async"
63
63
  Provides-Extra: compress
64
64
  Requires-Dist: lz4~=4.4; extra == "compress"
65
65
  Requires-Dist: python-snappy~=0.7; extra == "compress"
66
- Requires-Dist: zstandard~=0.23; extra == "compress"
66
+ Requires-Dist: zstandard~=0.24; extra == "compress"
67
67
  Requires-Dist: brotli~=1.1; extra == "compress"
68
68
  Provides-Extra: diag
69
69
  Requires-Dist: asttokens~=3.0; extra == "diag"
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=aT8yZ-Zh-9wfHl5Ym5ouiWC1i0cy7Q7RlhzavB6VLPI,8587
2
- omlish/__about__.py,sha256=_QVlo8CQjNk-OHJAjF73aaQcYeg4EcZVNzbbBB0SVoU,3576
2
+ omlish/__about__.py,sha256=iDAg-fMcGCRDczeTg78gCXGIynAhZMN-oYTNadqljJ0,3576
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
@@ -73,10 +73,10 @@ omlish/codecs/base.py,sha256=IVnJlduvhiH1imul4DPhl2gHBWS76774AV5h86dX0ls,2214
73
73
  omlish/codecs/bytes.py,sha256=3DxyQQCvFcP3mQ5G93f_mygXEb-7I8buM8EyzUcx2Is,2155
74
74
  omlish/codecs/chain.py,sha256=nbkL2nz0ZqT2lxYwSXktHh1YFTQ4Iii1Hp-fWjis6rc,532
75
75
  omlish/codecs/funcs.py,sha256=or0Jogczuzk7csDTRl-HURMEjl8LXXqxxXYK45xcM5w,855
76
- omlish/codecs/registry.py,sha256=PIf7XdwVX7Q85-MnyURtX9SKAYolK_r7wls9Z-qAsnA,3911
76
+ omlish/codecs/registry.py,sha256=_s-RKf06dlZhmXNH7Z2qbO8LPEtWeP-wgDAaHp9DFlg,3933
77
77
  omlish/codecs/standard.py,sha256=eiZ4u9ep0XrA4Z_D1zJI0vmWyuN8HLrX4Se_r_Cq_ZM,60
78
78
  omlish/codecs/text.py,sha256=uHhV8jBgH0iZgcrV0nl4-0a_9ofln4iFH4OXoVm2CW4,5709
79
- omlish/collections/__init__.py,sha256=oKrHZOcvB0a6onUsbsHGJ7d-sPVbYXBZ4Nt3uYR8OtQ,2805
79
+ omlish/collections/__init__.py,sha256=BIc806ri5Eq-kR03Ya2YfYTRI0g1rn_0haQPUqxXqys,2816
80
80
  omlish/collections/abc.py,sha256=p9zhL5oNV5WPyWmMn34fWfkuxPQAjOtL7WQA-Xsyhwk,2628
81
81
  omlish/collections/bimap.py,sha256=3szDCscPJlFRtkpyVQNWneg4s50mr6Rd0jdTzVEIcnE,1661
82
82
  omlish/collections/coerce.py,sha256=tAls15v_7p5bUN33R7Zbko87KW5toWHl9fRialCqyNY,7030
@@ -431,7 +431,7 @@ omlish/lang/casing.py,sha256=cFUlbDdXLhwnWwcYx4qnM5c4zGX7hIRUfcjiZbxUD28,4636
431
431
  omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
432
432
  omlish/lang/collections.py,sha256=XI76WcSi4SclWmEGirErg7EzQUfjtmiK2xSK7jJISzY,2528
433
433
  omlish/lang/comparison.py,sha256=MOwEG0Yny-jBPHO9kQto9FSRyeNpQW24UABsghkrHxY,1356
434
- omlish/lang/contextmanagers.py,sha256=7atRNgR13cgynKIgrDZNLq5qAV52xWy8ISeOVaL6HrQ,7627
434
+ omlish/lang/contextmanagers.py,sha256=na4T51jL0SMkC3oEJJsxdbAKgzSrfyFV6h9NCrQ3rX0,7685
435
435
  omlish/lang/datetimes.py,sha256=01tg21QOx-PWDlm-CSFTalym3vpqF0EKzeinmtcVNoU,379
436
436
  omlish/lang/descriptors.py,sha256=zBtgO9LjdSTGHNUgiIqswh78WOVoGH6KzS0NbgB1Wls,6572
437
437
  omlish/lang/enums.py,sha256=F9tflHfaAoV2MpyuhZzpfX9-H55M3zNa9hCszsngEo8,111
@@ -467,7 +467,7 @@ omlish/lang/imports/conditional.py,sha256=qxHYlE_xuwPJb6F9K8upagHxuYL0APPLWRVo50
467
467
  omlish/lang/imports/lazy.py,sha256=gDv7ffrGsPEAHZ9a1Myt7Uf-4vqWErhCd1DaS7SQL0c,1464
468
468
  omlish/lang/imports/proxyinit.py,sha256=prcQSZYdXSvZLsWZClNSOhIJVHNMuO8nD9NTtG-fFv4,12636
469
469
  omlish/lang/imports/resolution.py,sha256=DeRarn35Fryg5JhVhy8wbiC9lvr58AnllI9B_reswUE,2085
470
- omlish/lang/imports/traversal.py,sha256=LLic4zfhsSBzKF33_0qABBcjxfajc57mYRkeuj_Zuns,2855
470
+ omlish/lang/imports/traversal.py,sha256=pbFQIa880NGjSfcLsno2vE_G41_CLwDHb-7gWg2J3BI,2855
471
471
  omlish/lifecycles/__init__.py,sha256=1FjYceXs-4fc-S-C9zFYmc2axHs4znnQHcJVHdY7a6E,578
472
472
  omlish/lifecycles/abstract.py,sha256=c9UY7oxzYZ_neh5DPE4yv5HfuDv7B4Mj_9Zo-B8KDSs,1114
473
473
  omlish/lifecycles/base.py,sha256=DeUxARnOufWfBvhZQbonl1RVJgbrSeK5QNM6dWEuOwA,1398
@@ -518,8 +518,8 @@ omlish/logs/timing.py,sha256=qsQ3DB6swts1pxrFlmLWQzhH-3nzDrq1MUu7PxjjUyU,1519
518
518
  omlish/logs/utils.py,sha256=OkFWf1exmWImmT7BaSiIC7c0Fk9tAis-PRqo8H4ny3c,398
519
519
  omlish/manifests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
520
520
  omlish/manifests/base.py,sha256=Z5afzBJgI0tyTS8mPbYY4pYvoZu_xtdhRBOtZ3IIwzA,929
521
- omlish/manifests/globals.py,sha256=LZm4ueBjlC023uxL8zvivSyzMgx5O8kSbo9oNfhF_DE,206
522
- omlish/manifests/loading.py,sha256=iIX4XmQRlaqNMasSPStu3hcB_9t1y6iAFQ-Rydu9rcY,8068
521
+ omlish/manifests/globals.py,sha256=nrA85o8zFTEYv440Y1wgr7SmtW6AE_3jF_Dls6RB_nE,1661
522
+ omlish/manifests/loading.py,sha256=kzJwESneZB1mAK6PsVPXvfNjr-MOXL7bbKQ8gEmbVkU,11984
523
523
  omlish/manifests/static.py,sha256=7YwOVh_Ek9_aTrWsWNO8kWS10_j4K7yv3TpXZSHsvDY,501
524
524
  omlish/manifests/types.py,sha256=5hQuY-WZ9VMqHZXr-9Dayg380JsnX2vJzXyw6vC6UDs,317
525
525
  omlish/marshal/.dataclasses.json,sha256=wXWUy_IR8AolAa2RQnqn_mo2QnmVcvUJmayIykdVl0I,22
@@ -908,9 +908,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
908
908
  omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
909
909
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
910
910
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
911
- omlish-0.0.0.dev400.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
912
- omlish-0.0.0.dev400.dist-info/METADATA,sha256=plSr7XXGzb3LCmxU49UqfaZzRfgAlM003BveHzqlP8M,18825
913
- omlish-0.0.0.dev400.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
914
- omlish-0.0.0.dev400.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
915
- omlish-0.0.0.dev400.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
916
- omlish-0.0.0.dev400.dist-info/RECORD,,
911
+ omlish-0.0.0.dev402.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
912
+ omlish-0.0.0.dev402.dist-info/METADATA,sha256=vvELyku0Fo56crdctExjmjMC0AjhB2p8VclLoR2sxOE,18825
913
+ omlish-0.0.0.dev402.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
914
+ omlish-0.0.0.dev402.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
915
+ omlish-0.0.0.dev402.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
916
+ omlish-0.0.0.dev402.dist-info/RECORD,,