omlish 0.0.0.dev425__py3-none-any.whl → 0.0.0.dev427__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 +2 -2
- omlish/c3.py +4 -1
- omlish/configs/processing/flattening.py +1 -1
- omlish/configs/processing/merging.py +8 -6
- omlish/dataclasses/impl/concerns/doc.py +1 -1
- omlish/diag/_pycharm/runhack.py +1 -1
- omlish/diag/procfs.py +2 -2
- omlish/formats/json/stream/lexing.py +63 -16
- omlish/formats/json/stream/parsing.py +1 -1
- omlish/formats/json/stream/utils.py +2 -2
- omlish/formats/logfmt.py +8 -2
- omlish/funcs/genmachine.py +1 -1
- omlish/http/sse.py +1 -1
- omlish/inject/impl/injector.py +1 -1
- omlish/inject/impl/multis.py +2 -2
- omlish/inject/impl/providers.py +0 -4
- omlish/inject/impl/proxy.py +0 -2
- omlish/inject/scopes.py +0 -4
- omlish/io/buffers.py +1 -1
- omlish/lang/__init__.py +23 -13
- omlish/lang/{attrs.py → attrstorage.py} +15 -15
- omlish/lang/cached/property.py +2 -2
- omlish/lang/classes/simple.py +26 -4
- omlish/lang/collections.py +1 -1
- omlish/lang/iterables.py +2 -2
- omlish/lifecycles/contextmanagers.py +1 -1
- omlish/lifecycles/controller.py +1 -1
- omlish/lite/asyncs.py +5 -0
- omlish/lite/attrops.py +332 -0
- omlish/lite/cached.py +1 -1
- omlish/lite/maybes.py +2 -0
- omlish/lite/strings.py +0 -7
- omlish/lite/timing.py +4 -1
- omlish/logs/all.py +4 -0
- omlish/logs/base.py +138 -152
- omlish/logs/callers.py +3 -3
- omlish/logs/contexts.py +250 -0
- omlish/logs/infos.py +16 -5
- omlish/logs/modules.py +10 -0
- omlish/logs/protocols.py +7 -7
- omlish/logs/std/adapters.py +9 -5
- omlish/logs/std/records.py +26 -11
- omlish/logs/times.py +4 -6
- omlish/manifests/loading.py +6 -0
- omlish/os/atomics.py +1 -1
- omlish/reflect/types.py +22 -0
- omlish/sockets/server/server.py +1 -1
- {omlish-0.0.0.dev425.dist-info → omlish-0.0.0.dev427.dist-info}/METADATA +2 -2
- {omlish-0.0.0.dev425.dist-info → omlish-0.0.0.dev427.dist-info}/RECORD +53 -52
- omlish/lite/logs.py +0 -4
- omlish/lite/reprs.py +0 -85
- {omlish-0.0.0.dev425.dist-info → omlish-0.0.0.dev427.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev425.dist-info → omlish-0.0.0.dev427.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev425.dist-info → omlish-0.0.0.dev427.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev425.dist-info → omlish-0.0.0.dev427.dist-info}/top_level.txt +0 -0
omlish/lite/asyncs.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# ruff: noqa: UP045
|
1
2
|
import functools
|
2
3
|
import typing as ta
|
3
4
|
|
@@ -8,6 +9,10 @@ T = ta.TypeVar('T')
|
|
8
9
|
##
|
9
10
|
|
10
11
|
|
12
|
+
async def opt_await(aw: ta.Optional[ta.Awaitable[T]]) -> ta.Optional[T]:
|
13
|
+
return (await aw if aw is not None else None)
|
14
|
+
|
15
|
+
|
11
16
|
def as_async(fn: ta.Callable[..., T], *, wrap: bool = False) -> ta.Callable[..., ta.Awaitable[T]]:
|
12
17
|
async def inner(*args, **kwargs):
|
13
18
|
return fn(*args, **kwargs)
|
omlish/lite/attrops.py
ADDED
@@ -0,0 +1,332 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007 UP045
|
2
|
+
# @omlish-lite
|
3
|
+
"""
|
4
|
+
TODO:
|
5
|
+
- dotted paths!
|
6
|
+
- per-attr repr transform / filter
|
7
|
+
- __ne__ ? cases where it still matters
|
8
|
+
- ordering ?
|
9
|
+
"""
|
10
|
+
import types # noqa
|
11
|
+
import typing as ta
|
12
|
+
|
13
|
+
|
14
|
+
T = ta.TypeVar('T')
|
15
|
+
|
16
|
+
|
17
|
+
##
|
18
|
+
|
19
|
+
|
20
|
+
@ta.final
|
21
|
+
class AttrOps(ta.Generic[T]):
|
22
|
+
@ta.final
|
23
|
+
class Attr:
|
24
|
+
def __init__(
|
25
|
+
self,
|
26
|
+
name: str,
|
27
|
+
*,
|
28
|
+
display: ta.Optional[str] = None,
|
29
|
+
|
30
|
+
repr: bool = True, # noqa
|
31
|
+
hash: bool = True, # noqa
|
32
|
+
eq: bool = True,
|
33
|
+
) -> None:
|
34
|
+
if '.' in name:
|
35
|
+
raise NotImplementedError('Dotted paths not yet supported')
|
36
|
+
if not name.isidentifier() or name.startswith('__'):
|
37
|
+
raise AttributeError(f'Invalid attr: {name!r}')
|
38
|
+
self._name = name
|
39
|
+
|
40
|
+
if display is None:
|
41
|
+
display = name[1:] if name.startswith('_') and len(name) > 1 else name
|
42
|
+
self._display = display
|
43
|
+
|
44
|
+
self._repr = repr
|
45
|
+
self._hash = hash
|
46
|
+
self._eq = eq
|
47
|
+
|
48
|
+
@classmethod
|
49
|
+
def of(
|
50
|
+
cls,
|
51
|
+
o: ta.Union[
|
52
|
+
str,
|
53
|
+
ta.Tuple[str, str],
|
54
|
+
'AttrOps.Attr',
|
55
|
+
],
|
56
|
+
) -> 'AttrOps.Attr':
|
57
|
+
if isinstance(o, AttrOps.Attr):
|
58
|
+
return o
|
59
|
+
elif isinstance(o, str):
|
60
|
+
return cls(o)
|
61
|
+
else:
|
62
|
+
name, disp = o
|
63
|
+
return cls(
|
64
|
+
name,
|
65
|
+
display=disp,
|
66
|
+
)
|
67
|
+
|
68
|
+
@property
|
69
|
+
def name(self) -> str:
|
70
|
+
return self._name
|
71
|
+
|
72
|
+
@property
|
73
|
+
def display(self) -> str:
|
74
|
+
return self._display
|
75
|
+
|
76
|
+
@property
|
77
|
+
def hash(self) -> bool:
|
78
|
+
return self._hash
|
79
|
+
|
80
|
+
@property
|
81
|
+
def eq(self) -> bool:
|
82
|
+
return self._eq
|
83
|
+
|
84
|
+
@ta.overload
|
85
|
+
def __init__(
|
86
|
+
self,
|
87
|
+
*attrs: ta.Sequence[ta.Union[
|
88
|
+
str,
|
89
|
+
ta.Tuple[str, str],
|
90
|
+
Attr,
|
91
|
+
]],
|
92
|
+
with_module: bool = False,
|
93
|
+
use_qualname: bool = False,
|
94
|
+
with_id: bool = False,
|
95
|
+
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
96
|
+
recursive: bool = False,
|
97
|
+
subtypes_eq: bool = False,
|
98
|
+
) -> None:
|
99
|
+
...
|
100
|
+
|
101
|
+
@ta.overload
|
102
|
+
def __init__(
|
103
|
+
self,
|
104
|
+
attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
|
105
|
+
ta.Any,
|
106
|
+
ta.Tuple[str, ta.Any],
|
107
|
+
Attr,
|
108
|
+
], ...]],
|
109
|
+
/,
|
110
|
+
*,
|
111
|
+
with_module: bool = False,
|
112
|
+
use_qualname: bool = False,
|
113
|
+
with_id: bool = False,
|
114
|
+
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
115
|
+
recursive: bool = False,
|
116
|
+
subtypes_eq: bool = False,
|
117
|
+
) -> None:
|
118
|
+
...
|
119
|
+
|
120
|
+
def __init__(
|
121
|
+
self,
|
122
|
+
*args,
|
123
|
+
with_module=False,
|
124
|
+
use_qualname=False,
|
125
|
+
with_id=False,
|
126
|
+
repr_filter=None,
|
127
|
+
recursive=False,
|
128
|
+
subtypes_eq=False,
|
129
|
+
) -> None:
|
130
|
+
if args and len(args) == 1 and callable(args[0]):
|
131
|
+
self._attrs: ta.Sequence[AttrOps.Attr] = self._capture_attrs(args[0])
|
132
|
+
else:
|
133
|
+
self._attrs = list(map(AttrOps.Attr.of, args))
|
134
|
+
|
135
|
+
self._with_module: bool = with_module
|
136
|
+
self._use_qualname: bool = use_qualname
|
137
|
+
self._with_id: bool = with_id
|
138
|
+
self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
|
139
|
+
self._recursive: bool = recursive
|
140
|
+
self._subtypes_eq: bool = subtypes_eq
|
141
|
+
|
142
|
+
@property
|
143
|
+
def attrs(self) -> ta.Sequence[Attr]:
|
144
|
+
return self._attrs
|
145
|
+
|
146
|
+
#
|
147
|
+
|
148
|
+
@ta.final
|
149
|
+
class _AttrCapturer:
|
150
|
+
def __init__(self, fn):
|
151
|
+
self.__fn = fn
|
152
|
+
|
153
|
+
def __getattr__(self, attr):
|
154
|
+
return self.__fn(self, attr)
|
155
|
+
|
156
|
+
@classmethod
|
157
|
+
def _capture_attrs(cls, fn: ta.Callable) -> ta.Sequence[Attr]:
|
158
|
+
def access(parent, attr):
|
159
|
+
dct[(ret := cls._AttrCapturer(access))] = (parent, attr)
|
160
|
+
return ret
|
161
|
+
|
162
|
+
dct: dict = {}
|
163
|
+
raw = fn(root := cls._AttrCapturer(access))
|
164
|
+
|
165
|
+
def rec(cap): # noqa
|
166
|
+
if cap is root:
|
167
|
+
return
|
168
|
+
parent, attr = dct[cap]
|
169
|
+
yield from rec(parent)
|
170
|
+
yield attr
|
171
|
+
|
172
|
+
attrs: ta.List[AttrOps.Attr] = []
|
173
|
+
for o in raw:
|
174
|
+
if isinstance(o, AttrOps.Attr):
|
175
|
+
attrs.append(o)
|
176
|
+
continue
|
177
|
+
|
178
|
+
if isinstance(o, tuple):
|
179
|
+
disp, cap, = o
|
180
|
+
else:
|
181
|
+
disp, cap = None, o
|
182
|
+
|
183
|
+
path = tuple(rec(cap))
|
184
|
+
|
185
|
+
attrs.append(AttrOps.Attr(
|
186
|
+
'.'.join(path),
|
187
|
+
display=disp,
|
188
|
+
))
|
189
|
+
|
190
|
+
return attrs
|
191
|
+
|
192
|
+
#
|
193
|
+
|
194
|
+
_repr: ta.Callable[[T], str]
|
195
|
+
|
196
|
+
@property
|
197
|
+
def repr(self) -> ta.Callable[[T], str]:
|
198
|
+
try:
|
199
|
+
return self._repr
|
200
|
+
except AttributeError:
|
201
|
+
pass
|
202
|
+
|
203
|
+
def _repr(o: T) -> str:
|
204
|
+
vs = ', '.join(
|
205
|
+
f'{a._display}={v!r}' # noqa
|
206
|
+
for a in self._attrs
|
207
|
+
if a._repr # noqa
|
208
|
+
for v in [getattr(o, a._name)] # noqa
|
209
|
+
if self._repr_filter is None or self._repr_filter(v)
|
210
|
+
)
|
211
|
+
|
212
|
+
return (
|
213
|
+
f'{o.__class__.__module__ + "." if self._with_module else ""}'
|
214
|
+
f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
|
215
|
+
f'{("@" + hex(id(o))[2:]) if self._with_id else ""}'
|
216
|
+
f'({vs})'
|
217
|
+
)
|
218
|
+
|
219
|
+
if self._recursive:
|
220
|
+
_repr = self._reprlib().recursive_repr()(_repr)
|
221
|
+
|
222
|
+
self._repr = _repr
|
223
|
+
return _repr
|
224
|
+
|
225
|
+
_reprlib_: ta.ClassVar[ta.Any]
|
226
|
+
|
227
|
+
@classmethod
|
228
|
+
def _reprlib(cls) -> ta.Any:
|
229
|
+
try:
|
230
|
+
return cls._reprlib_
|
231
|
+
except AttributeError:
|
232
|
+
pass
|
233
|
+
|
234
|
+
import reprlib # noqa
|
235
|
+
|
236
|
+
cls._reprlib_ = reprlib
|
237
|
+
return reprlib
|
238
|
+
|
239
|
+
#
|
240
|
+
|
241
|
+
_hash: ta.Callable[[T], int]
|
242
|
+
|
243
|
+
@property
|
244
|
+
def hash(self) -> ta.Callable[[T], int]:
|
245
|
+
try:
|
246
|
+
return self._hash
|
247
|
+
except AttributeError:
|
248
|
+
pass
|
249
|
+
|
250
|
+
def _hash(o: T) -> int:
|
251
|
+
return hash(tuple(
|
252
|
+
getattr(o, a._name) # noqa
|
253
|
+
for a in self._attrs
|
254
|
+
if a._hash # noqa
|
255
|
+
))
|
256
|
+
|
257
|
+
self._hash = _hash
|
258
|
+
return _hash
|
259
|
+
|
260
|
+
#
|
261
|
+
|
262
|
+
_eq: ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']]
|
263
|
+
|
264
|
+
@property
|
265
|
+
def eq(self) -> ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']]:
|
266
|
+
try:
|
267
|
+
return self._eq
|
268
|
+
except AttributeError:
|
269
|
+
pass
|
270
|
+
|
271
|
+
def _eq(o: T, x: ta.Any) -> 'ta.Union[bool, types.NotImplementedType]':
|
272
|
+
if self._subtypes_eq:
|
273
|
+
if not isinstance(x, type(o)):
|
274
|
+
return NotImplemented
|
275
|
+
else:
|
276
|
+
if type(x) is not type(o):
|
277
|
+
return NotImplemented
|
278
|
+
|
279
|
+
return all(
|
280
|
+
getattr(o, a._name) == getattr(x, a._name) # noqa
|
281
|
+
for a in self._attrs
|
282
|
+
if a._eq # noqa
|
283
|
+
)
|
284
|
+
|
285
|
+
self._eq = _eq
|
286
|
+
return _eq
|
287
|
+
|
288
|
+
#
|
289
|
+
|
290
|
+
@property
|
291
|
+
def hash_eq(self) -> ta.Tuple[
|
292
|
+
ta.Callable[[T], int],
|
293
|
+
ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']],
|
294
|
+
]:
|
295
|
+
return (self.hash, self.eq)
|
296
|
+
|
297
|
+
@property
|
298
|
+
def repr_hash_eq(self) -> ta.Tuple[
|
299
|
+
ta.Callable[[T], str],
|
300
|
+
ta.Callable[[T], int],
|
301
|
+
ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']],
|
302
|
+
]:
|
303
|
+
return (self.repr, self.hash, self.eq)
|
304
|
+
|
305
|
+
#
|
306
|
+
|
307
|
+
def install(
|
308
|
+
self,
|
309
|
+
locals_dct: ta.MutableMapping[str, ta.Any],
|
310
|
+
*,
|
311
|
+
all: bool = False, # noqa
|
312
|
+
repr: bool = False, # noqa
|
313
|
+
hash: bool = False, # noqa
|
314
|
+
eq: bool = False,
|
315
|
+
) -> 'AttrOps[T]':
|
316
|
+
if repr or all:
|
317
|
+
locals_dct.update(__repr__=self.repr)
|
318
|
+
if hash or all:
|
319
|
+
locals_dct.update(__hash__=self.hash)
|
320
|
+
if eq or all:
|
321
|
+
locals_dct.update(__eq__=self.eq)
|
322
|
+
return self
|
323
|
+
|
324
|
+
|
325
|
+
attr_ops = AttrOps[ta.Any]
|
326
|
+
|
327
|
+
|
328
|
+
##
|
329
|
+
|
330
|
+
|
331
|
+
def attr_repr(obj: ta.Any, *attrs: str, **kwargs: ta.Any) -> str:
|
332
|
+
return AttrOps(*attrs, **kwargs).repr(obj)
|
omlish/lite/cached.py
CHANGED
@@ -21,7 +21,7 @@ class _AbstractCachedNullary:
|
|
21
21
|
def __call__(self, *args, **kwargs): # noqa
|
22
22
|
raise TypeError
|
23
23
|
|
24
|
-
def __get__(self, instance, owner): # noqa
|
24
|
+
def __get__(self, instance, owner=None): # noqa
|
25
25
|
bound = instance.__dict__[self._fn.__name__] = self.__class__(self._fn.__get__(instance, owner))
|
26
26
|
return bound
|
27
27
|
|
omlish/lite/maybes.py
CHANGED
@@ -148,6 +148,7 @@ class _Maybe(Maybe[T], Abstract):
|
|
148
148
|
return op and not sp
|
149
149
|
|
150
150
|
|
151
|
+
@ta.final
|
151
152
|
class _JustMaybe(_Maybe[T]):
|
152
153
|
__slots__ = ('_v', '_hash')
|
153
154
|
|
@@ -185,6 +186,7 @@ class _JustMaybe(_Maybe[T]):
|
|
185
186
|
)
|
186
187
|
|
187
188
|
|
189
|
+
@ta.final
|
188
190
|
class _EmptyMaybe(_Maybe[T]):
|
189
191
|
__slots__ = ()
|
190
192
|
|
omlish/lite/strings.py
CHANGED
@@ -73,13 +73,6 @@ def split_keep_delimiter(s, d):
|
|
73
73
|
##
|
74
74
|
|
75
75
|
|
76
|
-
def attr_repr(obj: ta.Any, *attrs: str) -> str:
|
77
|
-
return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
|
78
|
-
|
79
|
-
|
80
|
-
##
|
81
|
-
|
82
|
-
|
83
76
|
FORMAT_NUM_BYTES_SUFFIXES: ta.Sequence[str] = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB']
|
84
77
|
|
85
78
|
|
omlish/lite/timing.py
CHANGED