omlish 0.0.0.dev317__py3-none-any.whl → 0.0.0.dev319__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.dev317'
2
- __revision__ = 'fde65227a86537b0442352985307b74b7376b98e'
1
+ __version__ = '0.0.0.dev319'
2
+ __revision__ = 'db501bf0b4fbb5f1af2b467b004ffec22f3e769c'
3
3
 
4
4
 
5
5
  #
@@ -103,7 +103,7 @@ class Project(ProjectBase):
103
103
 
104
104
  'sqlean.py ~= 3.49',
105
105
 
106
- 'duckdb ~= 1.2',
106
+ 'duckdb ~= 1.3',
107
107
  ],
108
108
 
109
109
  'templates': [
@@ -12,6 +12,8 @@ from ...specs import FieldSpec
12
12
  def std_params_to_class_spec(
13
13
  p: StdParams,
14
14
  fields: ta.Sequence[FieldSpec],
15
+ *,
16
+ metadata: ta.Sequence[ta.Any] | None = None,
15
17
  ) -> ClassSpec:
16
18
  return ClassSpec(
17
19
  fields=fields,
@@ -27,4 +29,6 @@ def std_params_to_class_spec(
27
29
  kw_only=check.isinstance(p.kw_only, bool),
28
30
  slots=check.isinstance(p.slots, bool),
29
31
  weakref_slot=check.isinstance(p.weakref_slot, bool),
32
+
33
+ metadata=metadata,
30
34
  )
@@ -3,6 +3,7 @@ import typing as ta
3
3
 
4
4
  from .. import lang
5
5
  from .api.classes.conversion import std_params_to_class_spec
6
+ from .api.classes.metadata import extract_cls_metadata
6
7
  from .api.classes.params import get_class_spec
7
8
  from .api.fields.conversion import std_field_to_field_spec
8
9
  from .concerns.fields import InitFields
@@ -49,9 +50,12 @@ class ClassReflection:
49
50
  for f in dc.fields(self._cls) # noqa
50
51
  ]
51
52
 
53
+ cmd = extract_cls_metadata(self._cls, deep=True)
54
+
52
55
  cs = std_params_to_class_spec(
53
56
  p,
54
57
  fsl,
58
+ metadata=cmd.user_metadata or None,
55
59
  )
56
60
 
57
61
  return cs
@@ -59,6 +59,9 @@ class _cached_nullary: # noqa
59
59
  #
60
60
 
61
61
 
62
+ _repr = repr
63
+
64
+
62
65
  def _attr_repr(obj, *atts):
63
66
  return f'{obj.__class__.__name__}({", ".join(f"{a}={getattr(obj, a)!r}" for a in atts)})'
64
67
 
@@ -127,6 +130,109 @@ class AsJson:
127
130
  ##
128
131
 
129
132
 
133
+ class SysModule(AttrsClass, AsJson):
134
+ def __init__(
135
+ self,
136
+ name, # type: str
137
+ *,
138
+ seq=None, # type: int | None
139
+ repr=None, # type: str | None # noqa
140
+
141
+ origin=None, # type: str | None
142
+ file=None, # type: str | None
143
+ ) -> None:
144
+ super().__init__()
145
+
146
+ self._name = name
147
+
148
+ self._seq = seq
149
+ self._repr = repr
150
+
151
+ self._origin = origin
152
+ self._file = file
153
+
154
+ __attrs__ = (
155
+ 'name',
156
+
157
+ 'seq',
158
+ 'repr',
159
+
160
+ 'origin',
161
+ 'file',
162
+ )
163
+
164
+ @property
165
+ def name(self): # type: () -> str
166
+ return self._name
167
+
168
+ @property
169
+ def seq(self): # type: () -> int | None
170
+ return self._seq
171
+
172
+ @property
173
+ def repr(self): # type: () -> str | None
174
+ return self._repr
175
+
176
+ @property
177
+ def origin(self): # type: () -> str | None
178
+ return self._origin
179
+
180
+ @property
181
+ def file(self): # type: () -> str | None
182
+ return self._file
183
+
184
+ def as_json(self): # type: () -> dict[str, object]
185
+ return self.attrs_dict()
186
+
187
+
188
+ def build_sys_module(
189
+ name, # type: str
190
+ mod,
191
+ *,
192
+ seq=None, # type: int | None
193
+ ) -> SysModule:
194
+ kwargs = dict() # type: dict
195
+ kwargs.update(
196
+ name=name,
197
+
198
+ seq=seq,
199
+ repr=_repr(mod),
200
+ )
201
+
202
+ try:
203
+ spec = mod.__spec__
204
+ except AttributeError:
205
+ pass
206
+ else:
207
+ if spec is not None:
208
+ kwargs.update(origin=spec.origin)
209
+
210
+ try:
211
+ file = mod.__file__
212
+ except AttributeError:
213
+ pass
214
+ else:
215
+ kwargs.update(file=file)
216
+
217
+ return SysModule(**kwargs)
218
+
219
+
220
+ def build_sys_modules(dct=None): # type: (dict[str, object] | None) -> list[SysModule]
221
+ if dct is None:
222
+ dct_ = sys.modules
223
+ else:
224
+ dct_ = dct # type: ignore
225
+
226
+ lst = [] # type: list[SysModule]
227
+ for i, (n, m) in enumerate(dct_.items()):
228
+ lst.append(build_sys_module(n, m, seq=i))
229
+
230
+ return lst
231
+
232
+
233
+ ##
234
+
235
+
130
236
  class RunEnv(AttrsClass, AsJson):
131
237
  def __init__(
132
238
  self,
@@ -143,6 +249,7 @@ class RunEnv(AttrsClass, AsJson):
143
249
  pycharm_hosted=None, # type: bool | None
144
250
 
145
251
  sys_path=None, # type: list[str] | None
252
+ sys_modules=None, # type: list[SysModule] | None
146
253
  ) -> None:
147
254
  super().__init__()
148
255
 
@@ -182,6 +289,10 @@ class RunEnv(AttrsClass, AsJson):
182
289
  sys_path = list(sys.path)
183
290
  self._sys_path = sys_path
184
291
 
292
+ if sys_modules is None:
293
+ sys_modules = build_sys_modules()
294
+ self._sys_modules = sys_modules
295
+
185
296
  __attrs__ = (
186
297
  'argv',
187
298
  'orig_argv',
@@ -195,6 +306,7 @@ class RunEnv(AttrsClass, AsJson):
195
306
  'pycharm_hosted',
196
307
 
197
308
  'sys_path',
309
+ 'sys_modules',
198
310
  )
199
311
 
200
312
  @property
@@ -233,8 +345,15 @@ class RunEnv(AttrsClass, AsJson):
233
345
  def sys_path(self): # type: () -> list[str]
234
346
  return self._sys_path
235
347
 
348
+ @property
349
+ def sys_modules(self): # type: () -> list[SysModule]
350
+ return self._sys_modules
351
+
236
352
  def as_json(self): # type: () -> dict[str, object]
237
- return self.attrs_dict()
353
+ return {
354
+ **self.attrs_dict(),
355
+ 'sys_modules': [m.as_json() for m in self.sys_modules],
356
+ }
238
357
 
239
358
 
240
359
  ##
@@ -29,6 +29,7 @@ class Method(ta.Generic[P, R]):
29
29
  func: ta.Callable,
30
30
  *,
31
31
  installable: bool = False,
32
+ requires_override: bool = False,
32
33
  ) -> None:
33
34
  super().__init__()
34
35
 
@@ -37,6 +38,7 @@ class Method(ta.Generic[P, R]):
37
38
 
38
39
  self._func = func
39
40
  self._installable = installable
41
+ self._requires_override = requires_override
40
42
 
41
43
  self._impls: ta.MutableMapping[ta.Callable, frozenset[type] | None] = weakref.WeakKeyDictionary()
42
44
 
@@ -97,33 +99,73 @@ class Method(ta.Generic[P, R]):
97
99
 
98
100
  return impl
99
101
 
102
+ def _is_impl(self, obj: ta.Any) -> bool:
103
+ try:
104
+ hash(obj)
105
+ except TypeError:
106
+ return False
107
+
108
+ return obj in self._impls
109
+
100
110
  def build_attr_dispatcher(self, instance_cls: type, owner_cls: type | None = None) -> Dispatcher[str]:
101
- disp: Dispatcher[str] = Dispatcher()
111
+ if owner_cls is None:
112
+ owner_cls = instance_cls
102
113
 
103
- mro_dct = lang.mro_dict(instance_cls, owner_cls)
104
- seen: ta.Mapping[ta.Any, str] = {}
105
- for nam, att in mro_dct.items():
106
- try:
107
- hash(att)
108
- except TypeError:
109
- continue
114
+ mro = instance_cls.__mro__[-2::-1]
115
+ try:
116
+ mro_pos = mro.index(owner_cls)
117
+ except ValueError:
118
+ raise TypeError(f'Owner class {owner_cls} not in mro of instance class {instance_cls}') from None
119
+
120
+ mro_dct: dict[str, list[tuple[type, ta.Any]]] = {}
121
+ for cur_cls in mro[:mro_pos + 1]:
122
+ for att, obj in cur_cls.__dict__.items():
123
+ if att not in mro_dct:
124
+ if not self._is_impl(obj):
125
+ continue
126
+
127
+ try:
128
+ lst = mro_dct[att]
129
+ except KeyError:
130
+ lst = mro_dct[att] = []
131
+ lst.append((cur_cls, obj))
110
132
 
111
- if att not in self._impls:
133
+ #
134
+
135
+ disp: Dispatcher[str] = Dispatcher()
136
+
137
+ seen: dict[ta.Any, str] = {}
138
+ for att, lst in mro_dct.items():
139
+ if not lst:
140
+ raise RuntimeError
141
+ _, obj = lst[-1]
142
+
143
+ if len(lst) > 1:
144
+ if self._requires_override and not lang.is_override(obj):
145
+ raise lang.RequiresOverrideError(
146
+ att,
147
+ instance_cls,
148
+ lst[-1][0],
149
+ lst[0][0],
150
+ )
151
+
152
+ if not self._is_impl(obj):
112
153
  continue
113
- cls_set = self._impls[att]
114
154
 
155
+ cls_set = self._impls[obj]
115
156
  if cls_set is None:
116
- cls_set = get_impl_func_cls_set(att, arg_offset=1)
117
- self._impls[att] = cls_set
157
+ cls_set = get_impl_func_cls_set(obj, arg_offset=1)
158
+ self._impls[obj] = cls_set
118
159
 
119
160
  try:
120
- ex_nam = seen[att]
161
+ ex_att = seen[obj]
121
162
  except KeyError:
122
163
  pass
123
164
  else:
124
- raise TypeError(f'Duplicate impl: {owner_cls} {instance_cls} {nam} {ex_nam}')
165
+ raise TypeError(f'Duplicate impl: {owner_cls} {instance_cls} {att} {ex_att}')
166
+ seen[obj] = att
125
167
 
126
- disp.register(nam, cls_set)
168
+ disp.register(att, cls_set)
127
169
 
128
170
  return disp
129
171
 
@@ -186,19 +228,42 @@ class Method(ta.Generic[P, R]):
186
228
 
187
229
 
188
230
  @ta.overload
189
- def method(func: ta.Callable[P, R], /, *, installable: bool = False) -> Method[P, R]: # noqa
231
+ def method(
232
+ func: ta.Callable[P, R],
233
+ /,
234
+ *,
235
+ installable: bool = False,
236
+ requires_override: bool = False,
237
+ ) -> Method[P, R]: # noqa
190
238
  ...
191
239
 
192
240
 
193
241
  @ta.overload
194
- def method(func: None = None, /, *, installable: bool = False) -> ta.Callable[[ta.Callable[P, R]], Method[P, R]]: # noqa
242
+ def method(
243
+ func: None = None,
244
+ /,
245
+ *,
246
+ installable: bool = False,
247
+ requires_override: bool = False,
248
+ ) -> ta.Callable[[ta.Callable[P, R]], Method[P, R]]: # noqa
195
249
  ...
196
250
 
197
251
 
198
- def method(func=None, /, *, installable=False): # noqa
199
- kw = dict(installable=installable)
252
+ def method(
253
+ func=None,
254
+ /,
255
+ *,
256
+ installable=False,
257
+ requires_override=False,
258
+ ):
259
+ kw = dict(
260
+ installable=installable,
261
+ requires_override=requires_override,
262
+ )
263
+
200
264
  if func is None:
201
265
  return functools.partial(Method, **kw)
266
+
202
267
  return Method(func, **kw)
203
268
 
204
269
 
omlish/lang/__init__.py CHANGED
@@ -252,6 +252,15 @@ from .outcomes import ( # noqa
252
252
  value,
253
253
  )
254
254
 
255
+ from .overrides import ( # noqa
256
+ needs_override,
257
+
258
+ is_override,
259
+
260
+ RequiresOverrideError,
261
+ RequiresOverride,
262
+ )
263
+
255
264
  from .params import ( # noqa
256
265
  ArgsParam,
257
266
  KwOnlyParam,
@@ -0,0 +1,82 @@
1
+ import types
2
+ import typing as ta
3
+
4
+ from .descriptors import unwrap_func
5
+
6
+
7
+ ##
8
+
9
+
10
+ class _EmptyClass:
11
+ pass
12
+
13
+
14
+ _OVERRIDE_NOT_NEEDED_ATTRS: ta.AbstractSet[str] = {
15
+ *_EmptyClass.__dict__,
16
+ }
17
+
18
+
19
+ def needs_override(attr: str, obj: ta.Any) -> bool:
20
+ if attr in _OVERRIDE_NOT_NEEDED_ATTRS:
21
+ return False
22
+
23
+ return True
24
+
25
+
26
+ ##
27
+
28
+
29
+ def is_override(obj: ta.Any) -> bool:
30
+ if isinstance(obj, types.FunctionType):
31
+ fn = unwrap_func(obj)
32
+ if getattr(fn, '__override__', False):
33
+ return True
34
+
35
+ return False
36
+
37
+
38
+ ##
39
+
40
+
41
+ class RequiresOverrideError(TypeError):
42
+ def __init__(
43
+ self,
44
+ att: str | None = None,
45
+ cls: type | None = None,
46
+ mro_cls: type | None = None,
47
+ owner_cls: type | None = None,
48
+ ) -> None:
49
+ super().__init__(' '.join([
50
+ 'Attribute',
51
+ *([f'{att!r}'] if att is not None else []),
52
+ *([f'on class {cls.__qualname__}'] if cls is not None else []),
53
+ *([f'from mro class {mro_cls.__qualname__}'] if mro_cls is not None and mro_cls is not cls else []),
54
+ f'is not marked as a @typing.override',
55
+ *([f'from owning class {owner_cls.__qualname__}'] if owner_cls is not None else []),
56
+ ]))
57
+
58
+ self.att = att
59
+ self.cls = cls
60
+ self.mro_cls = mro_cls
61
+ self.owner_cls = owner_cls
62
+
63
+
64
+ class RequiresOverride:
65
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
66
+ super().__init_subclass__(**kwargs)
67
+
68
+ req_ovr_dct: dict[str, type] = {}
69
+ for m_cls in reversed(cls.__mro__):
70
+ for a, o in m_cls.__dict__.items():
71
+ if a in req_ovr_dct and not is_override(o):
72
+ raise RequiresOverrideError(
73
+ a,
74
+ cls,
75
+ m_cls,
76
+ req_ovr_dct[a],
77
+ )
78
+
79
+ if RequiresOverride in m_cls.__bases__:
80
+ for a, o in m_cls.__dict__.items():
81
+ if needs_override(a, o):
82
+ req_ovr_dct.setdefault(a, m_cls)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev317
3
+ Version: 0.0.0.dev319
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -41,7 +41,7 @@ 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
43
  Requires-Dist: sqlean.py~=3.49; extra == "all"
44
- Requires-Dist: duckdb~=1.2; extra == "all"
44
+ Requires-Dist: duckdb~=1.3; extra == "all"
45
45
  Requires-Dist: markupsafe~=3.0; extra == "all"
46
46
  Requires-Dist: jinja2~=3.1; extra == "all"
47
47
  Requires-Dist: pytest~=8.3; extra == "all"
@@ -89,7 +89,7 @@ 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
91
  Requires-Dist: sqlean.py~=3.49; extra == "sqldrivers"
92
- Requires-Dist: duckdb~=1.2; extra == "sqldrivers"
92
+ Requires-Dist: duckdb~=1.3; extra == "sqldrivers"
93
93
  Provides-Extra: templates
94
94
  Requires-Dist: markupsafe~=3.0; extra == "templates"
95
95
  Requires-Dist: jinja2~=3.1; extra == "templates"
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=orgsRvtpHu8tdhaCvlP9v3P495OJopYYiHKjK68WtWg,8587
2
- omlish/__about__.py,sha256=XvJduE7LyT8sT8wf4Tcj6mGwYJh0_bub6Rmk7aliJpA,3478
2
+ omlish/__about__.py,sha256=BUm8C0RUF_mH5RRsEW0hH9yf1ygPXOnka9jzpOJkyck,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
@@ -139,12 +139,12 @@ omlish/dataclasses/debug.py,sha256=giBiv6aXvX0IagwNCW64qBzNjfOFr3-VmgDy_KYlb-k,2
139
139
  omlish/dataclasses/errors.py,sha256=tyv3WR6az66uGGiq9FIuCHvy1Ef-G7zeMY7mMG6hy2Y,2527
140
140
  omlish/dataclasses/inspect.py,sha256=BlpPghVCU3w_YDnONEqqE99YHzJM2q3eoqe39YX25Ko,4596
141
141
  omlish/dataclasses/internals.py,sha256=vIGCZnStgD3ef4drYRtVOrxhxmAPa0vJpo4pXcDcQvM,3073
142
- omlish/dataclasses/reflection.py,sha256=5N4acL27xwSnQJvoks6ts2JseGfwL_P9D2gM9vqtAFM,2243
142
+ omlish/dataclasses/reflection.py,sha256=FSSTiS7pGTmDrYNkS6fZzaMSe8qtSvDv5Pgz0T55qXg,2404
143
143
  omlish/dataclasses/specs.py,sha256=r9hpIWy83ODiB1n7wTf7JL5fiCeeT8fWbMvxs7c4e3g,6148
144
144
  omlish/dataclasses/utils.py,sha256=gv6za6oJYBr1VaeGd7oXqq9lhBs_sxkpC27XYzJggno,1870
145
145
  omlish/dataclasses/api/__init__.py,sha256=k5iS9QOwf_f4iOfGffYhnqDOcmEIwEUUTp00u11kIPM,455
146
146
  omlish/dataclasses/api/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
147
- omlish/dataclasses/api/classes/conversion.py,sha256=x1Ayo5W3t8lVh10KGH_ZBJ_kK7HqcdI2LdJA6mR_WXQ,810
147
+ omlish/dataclasses/api/classes/conversion.py,sha256=U3g5S-HefJrg4to1BF8XnlEWqMxFeGEqVt8o5OTQK-U,902
148
148
  omlish/dataclasses/api/classes/decorator.py,sha256=q-m05j6VhJ9_00TmrXBvwmv0_TFPTD8OURi1KbKo9-4,3933
149
149
  omlish/dataclasses/api/classes/make.py,sha256=Q_8ZVjhhFEUstIZA3Ht_vlGptYjTcJqX48qT57W7SZw,2820
150
150
  omlish/dataclasses/api/classes/metadata.py,sha256=ocUu75VWOdZA8-R7K95yPhQtS0sFZB1NtqCdzXyDNeQ,2769
@@ -214,7 +214,7 @@ omlish/diag/pycharm.py,sha256=Z2W-Viqw5xq08ZC4z36skpozfYw_qNNhWQx_GYr2D0k,4695
214
214
  omlish/diag/pydevd.py,sha256=UN55ZjkWLCVyHxE2CNRRYamuvSKfzWsn0D5oczRTXO4,7536
215
215
  omlish/diag/threads.py,sha256=1-x02VCDZ407gfbtXm1pWK-ubqhqfePm9PMqkHCVoqk,3642
216
216
  omlish/diag/_pycharm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
217
- omlish/diag/_pycharm/runhack.py,sha256=O37sduvkx99uQaEg_XWLDBJlUxaqgd2LkjmdGaUT6e4,35432
217
+ omlish/diag/_pycharm/runhack.py,sha256=f4R9SOH0nDfO2WqPh0xQ9-45qOLrtTVysS-hSwtbdOA,37864
218
218
  omlish/diag/replserver/__init__.py,sha256=uLo6V2aQ29v9z3IMELlPDSlG3_2iOT4-_X8VniF-EgE,235
219
219
  omlish/diag/replserver/__main__.py,sha256=LmU41lQ58bm1h4Mx7S8zhE_uEBSC6kPcp9mn5JRpulA,32
220
220
  omlish/diag/replserver/console.py,sha256=XzBDVhYlr8FY6ym4OwoaIHuFOHnGK3dTYlMDIOMUUlA,7410
@@ -225,7 +225,7 @@ omlish/dispatch/_dispatch3.py,sha256=9Zjd7bINAC3keiaBdssc4v5dY0-8OI6XooV2DR9U7Z0
225
225
  omlish/dispatch/dispatch.py,sha256=KA5l49AiGLRjp4J7RDJW9RiDp9WUD1ewR1AOPEF8g38,3062
226
226
  omlish/dispatch/functions.py,sha256=cwNzGIg2ZIalEgn9I03cnJVbMTHjWloyDTaowlO3UPs,1524
227
227
  omlish/dispatch/impls.py,sha256=K_okKvpZml4NkTHJmTVyMQSrIaIJcqTEgkreGwukaOw,1895
228
- omlish/dispatch/methods.py,sha256=CeGVwiUdeadzyOe0xQVY_jegyj0tdHLQZpaIlLkJNnY,7330
228
+ omlish/dispatch/methods.py,sha256=sSGA52swdrdHEbm_jAPBZVoKP9xMIfVcw2MnTvIJtrI,8913
229
229
  omlish/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
230
  omlish/docker/all.py,sha256=xXRgJgLGPwAtr7bDMJ_Dp9jTfOwfGvohNhc6LsoELJc,514
231
231
  omlish/docker/cli.py,sha256=gtb9kitVfGnd4cr587NsVVk8D5Ok5y5SAsqD_SwGrSA,2565
@@ -403,7 +403,7 @@ omlish/iterators/iterators.py,sha256=RxW35yQ5ed8vBQ22IqpDXFx-i5JiLQdp7-pkMZXhJJ8
403
403
  omlish/iterators/recipes.py,sha256=wOwOZg-zWG9Zc3wcAxJFSe2rtavVBYwZOfG09qYEx_4,472
404
404
  omlish/iterators/tools.py,sha256=c4hArZEVV8y9_dFfmRwakusv1cWJLT4MkTkGRjnGN5U,2556
405
405
  omlish/iterators/unique.py,sha256=Nw0pSaNEcHAkve0ugfLPvJcirDOn9ECyC5wIL8JlJKI,1395
406
- omlish/lang/__init__.py,sha256=Zs5YE5F7rq2cdEqK2e6QuamTQGGwLaM0OP_RNOmcT1A,5921
406
+ omlish/lang/__init__.py,sha256=ZtAmS2HiXPaJexoyPXD2fCl-8DNA4s8zlErlvhU_2o0,6045
407
407
  omlish/lang/attrs.py,sha256=i7euRF81uNF8QDmUVXSK_BtqLGshaMi4VVdUnMjiMwg,5050
408
408
  omlish/lang/casing.py,sha256=cFUlbDdXLhwnWwcYx4qnM5c4zGX7hIRUfcjiZbxUD28,4636
409
409
  omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
@@ -419,6 +419,7 @@ omlish/lang/imports.py,sha256=y9W9Y-d_cQ35QCLuSIPoa6vnEqSErFCz8b-34IH128U,10552
419
419
  omlish/lang/iterables.py,sha256=StoGp9yaP3njdLKHoWYcEevO3eE8SHEPYl5_avZob24,2149
420
420
  omlish/lang/objects.py,sha256=nbxBHfQHVw0OG4qeSTP2GvIiFIcH2tbbitY8y-mYPPo,5959
421
421
  omlish/lang/outcomes.py,sha256=mpFy_VoM-b74L1aCFsjsZVUHx_icZ1AHMOKeVesjOp4,8628
422
+ omlish/lang/overrides.py,sha256=IBzK6ljfLX6TLgIyKTSjhqTLcuKRkQNVtEOnBLS4nuA,2095
422
423
  omlish/lang/params.py,sha256=sfbNoGrKCsAtubFufj_uh_WKshIgA8fqJ4PmLH1PH00,6639
423
424
  omlish/lang/recursion.py,sha256=1VfSqzKO-8Is3t9LKw0W4jwPfE0aBS70EUlbUxAx4eE,1900
424
425
  omlish/lang/resolving.py,sha256=ei9LDyJexsMMHB9z8diUkNmynWhd_da7h7TqrMYM6lA,1611
@@ -853,9 +854,9 @@ omlish/typedvalues/holder.py,sha256=ZTnHiw-K38ciOBLEdwgrltr7Xp8jjEs_0Lp69DH-G-o,
853
854
  omlish/typedvalues/marshal.py,sha256=hWHRLcrGav7lvXJDtb9bNI0ickl4SKPQ6F4BbTpqw3A,4219
854
855
  omlish/typedvalues/reflect.py,sha256=Ih1YgU-srUjsvBn_P7C66f73_VCvcwqE3ffeBnZBgt4,674
855
856
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
856
- omlish-0.0.0.dev317.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
857
- omlish-0.0.0.dev317.dist-info/METADATA,sha256=4Z0c7koet4xBZgji9URV0S85ozghSxQShBteed3cg4s,4416
858
- omlish-0.0.0.dev317.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
859
- omlish-0.0.0.dev317.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
860
- omlish-0.0.0.dev317.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
861
- omlish-0.0.0.dev317.dist-info/RECORD,,
857
+ omlish-0.0.0.dev319.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
858
+ omlish-0.0.0.dev319.dist-info/METADATA,sha256=AJfjWjvSfK3uESd-jYGGUmEgPjkW22rJLSBh3h6hGbk,4416
859
+ omlish-0.0.0.dev319.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
860
+ omlish-0.0.0.dev319.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
861
+ omlish-0.0.0.dev319.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
862
+ omlish-0.0.0.dev319.dist-info/RECORD,,