omlish 0.0.0.dev430__py3-none-any.whl → 0.0.0.dev432__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/asyncs/ioproxy/proxy.py +1 -1
- omlish/concurrent/__init__.py +17 -11
- omlish/funcs/match.py +1 -1
- omlish/lang/imports/proxyinit.py +4 -3
- omlish/logs/all.py +10 -12
- omlish/logs/base.py +0 -30
- omlish/logs/contexts.py +71 -177
- omlish/logs/formatters.py +13 -0
- omlish/logs/infos.py +347 -90
- omlish/logs/standard.py +10 -6
- omlish/logs/std/formatters.py +25 -0
- omlish/logs/std/loggers.py +9 -9
- omlish/logs/std/records.py +571 -211
- omlish/logs/typed/values.py +2 -2
- omlish/math/fixed.py +2 -2
- omlish/secrets/secrets.py +3 -0
- {omlish-0.0.0.dev430.dist-info → omlish-0.0.0.dev432.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev430.dist-info → omlish-0.0.0.dev432.dist-info}/RECORD +23 -23
- omlish/logs/callers.py +0 -75
- omlish/logs/times.py +0 -89
- {omlish-0.0.0.dev430.dist-info → omlish-0.0.0.dev432.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev430.dist-info → omlish-0.0.0.dev432.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev430.dist-info → omlish-0.0.0.dev432.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev430.dist-info → omlish-0.0.0.dev432.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/asyncs/ioproxy/proxy.py
CHANGED
@@ -104,7 +104,7 @@ class AsyncIoProxy:
|
|
104
104
|
__proxied_cls__: ta.ClassVar[type]
|
105
105
|
|
106
106
|
def __init_subclass__(cls, *, proxied_cls=None, **kwargs): # noqa
|
107
|
-
super().__init_subclass__()
|
107
|
+
super().__init_subclass__(**kwargs)
|
108
108
|
|
109
109
|
cls.__proxied_cls__ = check.isinstance(proxied_cls, (type, None))
|
110
110
|
|
omlish/concurrent/__init__.py
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
-
from
|
2
|
-
|
3
|
-
|
4
|
-
)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
from .. import lang as _lang
|
2
|
+
|
3
|
+
|
4
|
+
with _lang.auto_proxy_init(globals()):
|
5
|
+
##
|
6
|
+
|
7
|
+
from .executors import ( # noqa
|
8
|
+
ImmediateExecutor,
|
9
|
+
new_executor,
|
10
|
+
)
|
11
|
+
|
12
|
+
from .futures import ( # noqa
|
13
|
+
FutureError,
|
14
|
+
FutureTimeoutError,
|
15
|
+
wait_futures,
|
16
|
+
wait_dependent_futures,
|
17
|
+
)
|
omlish/funcs/match.py
CHANGED
@@ -208,7 +208,7 @@ class MatchFnClass(MatchFn[P, T]):
|
|
208
208
|
return mf
|
209
209
|
|
210
210
|
def __init_subclass__(cls, strict: bool = False, **kwargs: ta.Any) -> None:
|
211
|
-
super().__init_subclass__()
|
211
|
+
super().__init_subclass__(**kwargs)
|
212
212
|
|
213
213
|
if '_cls_match_fn' in cls.__dict__:
|
214
214
|
raise AttributeError('_cls_match_fn')
|
omlish/lang/imports/proxyinit.py
CHANGED
@@ -644,9 +644,10 @@ def auto_proxy_init(
|
|
644
644
|
update_exports: bool = False,
|
645
645
|
) -> ta.Iterator[AutoProxyInit]:
|
646
646
|
"""
|
647
|
-
This is a bit extreme
|
648
|
-
|
649
|
-
|
647
|
+
This is a bit extreme, but worth it. For simplicity, it currently relies on temporarily patching
|
648
|
+
`__builtins__.__import__` for the duration of its context manager, but it can be switched to use any number of other
|
649
|
+
import hooks (like `sys.meta_path`). It does not rely on any permanent modification to import machinery, only for
|
650
|
+
the duration of its capture.
|
650
651
|
"""
|
651
652
|
|
652
653
|
inst = AutoProxyInit(
|
omlish/logs/all.py
CHANGED
@@ -9,6 +9,10 @@ with _lang.auto_proxy_init(globals()):
|
|
9
9
|
TidLoggingFilter,
|
10
10
|
)
|
11
11
|
|
12
|
+
from .std.formatters import ( # noqa
|
13
|
+
StdLoggingFormatter,
|
14
|
+
)
|
15
|
+
|
12
16
|
from .std.handlers import ( # noqa
|
13
17
|
ListLoggingHandler,
|
14
18
|
)
|
@@ -44,23 +48,17 @@ with _lang.auto_proxy_init(globals()):
|
|
44
48
|
AsyncNopLogger,
|
45
49
|
)
|
46
50
|
|
47
|
-
from .callers import ( # noqa
|
48
|
-
LoggingCaller,
|
49
|
-
)
|
50
|
-
|
51
51
|
from .contexts import ( # noqa
|
52
|
-
LoggingExcInfoTuple,
|
53
|
-
LoggingExcInfo,
|
54
|
-
|
55
52
|
LoggingContext,
|
56
53
|
)
|
57
54
|
|
55
|
+
from .formatters import ( # noqa
|
56
|
+
LoggingContextFormatter,
|
57
|
+
)
|
58
|
+
|
58
59
|
from .infos import ( # noqa
|
59
|
-
|
60
|
-
|
61
|
-
LoggingProcessInfo,
|
62
|
-
LoggingMultiprocessingInfo,
|
63
|
-
LoggingAsyncioTaskInfo,
|
60
|
+
LoggingContextInfo,
|
61
|
+
LoggingContextInfos,
|
64
62
|
)
|
65
63
|
|
66
64
|
from .levels import ( # noqa
|
omlish/logs/base.py
CHANGED
@@ -166,36 +166,6 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
166
166
|
|
167
167
|
##
|
168
168
|
|
169
|
-
@classmethod
|
170
|
-
def _prepare_msg_args(cls, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any) -> ta.Tuple[str, tuple]:
|
171
|
-
if callable(msg):
|
172
|
-
if args:
|
173
|
-
raise TypeError(f'Must not provide both a message function and args: {msg=} {args=}')
|
174
|
-
x = msg()
|
175
|
-
if isinstance(x, str):
|
176
|
-
return x, ()
|
177
|
-
elif isinstance(x, tuple):
|
178
|
-
if x:
|
179
|
-
return x[0], x[1:]
|
180
|
-
else:
|
181
|
-
return '', ()
|
182
|
-
else:
|
183
|
-
raise TypeError(x)
|
184
|
-
|
185
|
-
elif isinstance(msg, tuple):
|
186
|
-
if args:
|
187
|
-
raise TypeError(f'Must not provide both a tuple message and args: {msg=} {args=}')
|
188
|
-
if msg:
|
189
|
-
return msg[0], msg[1:]
|
190
|
-
else:
|
191
|
-
return '', ()
|
192
|
-
|
193
|
-
elif isinstance(msg, str):
|
194
|
-
return msg, args
|
195
|
-
|
196
|
-
else:
|
197
|
-
raise TypeError(msg)
|
198
|
-
|
199
169
|
@abc.abstractmethod
|
200
170
|
def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> T: # noqa
|
201
171
|
raise NotImplementedError
|
omlish/logs/contexts.py
CHANGED
@@ -1,94 +1,64 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007 UP045 UP046
|
2
2
|
# @omlish-lite
|
3
3
|
import abc
|
4
|
-
import sys
|
5
4
|
import time
|
6
|
-
import types
|
7
5
|
import typing as ta
|
8
6
|
|
9
7
|
from ..lite.abstract import Abstract
|
10
|
-
from .
|
11
|
-
from .infos import
|
12
|
-
from .infos import
|
13
|
-
from .infos import
|
14
|
-
from .infos import LoggingSourceFileInfo
|
15
|
-
from .infos import LoggingThreadInfo
|
8
|
+
from .infos import LoggingContextInfo
|
9
|
+
from .infos import LoggingContextInfos
|
10
|
+
from .infos import LoggingExcInfoArg
|
11
|
+
from .infos import LoggingMsgFn
|
16
12
|
from .levels import LogLevel
|
17
|
-
from .levels import NamedLogLevel
|
18
|
-
from .times import LoggingTimeFields
|
19
13
|
|
20
14
|
|
21
|
-
|
22
|
-
LoggingExcInfo = ta.Union[BaseException, LoggingExcInfoTuple] # ta.TypeAlias
|
23
|
-
LoggingExcInfoArg = ta.Union[LoggingExcInfo, bool, None] # ta.TypeAlias
|
15
|
+
LoggingContextInfoT = ta.TypeVar('LoggingContextInfoT', bound=LoggingContextInfo)
|
24
16
|
|
25
17
|
|
26
18
|
##
|
27
19
|
|
28
20
|
|
29
21
|
class LoggingContext(Abstract):
|
30
|
-
@property
|
31
22
|
@abc.abstractmethod
|
32
|
-
def
|
23
|
+
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
33
24
|
raise NotImplementedError
|
34
25
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@abc.abstractmethod
|
39
|
-
def time_ns(self) -> int:
|
40
|
-
raise NotImplementedError
|
41
|
-
|
42
|
-
@property
|
43
|
-
@abc.abstractmethod
|
44
|
-
def times(self) -> LoggingTimeFields:
|
45
|
-
raise NotImplementedError
|
46
|
-
|
47
|
-
#
|
48
|
-
|
49
|
-
@property
|
50
|
-
@abc.abstractmethod
|
51
|
-
def exc_info(self) -> ta.Optional[LoggingExcInfo]:
|
52
|
-
raise NotImplementedError
|
26
|
+
@ta.final
|
27
|
+
def __getitem__(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
28
|
+
return self.get_info(ty)
|
53
29
|
|
54
|
-
@
|
55
|
-
|
56
|
-
|
57
|
-
|
30
|
+
@ta.final
|
31
|
+
def must_get_info(self, ty: ta.Type[LoggingContextInfoT]) -> LoggingContextInfoT:
|
32
|
+
if (info := self.get_info(ty)) is None:
|
33
|
+
raise TypeError(f'LoggingContextInfo absent: {ty}')
|
34
|
+
return info
|
58
35
|
|
59
|
-
#
|
60
36
|
|
61
|
-
|
62
|
-
|
63
|
-
|
37
|
+
@ta.final
|
38
|
+
class SimpleLoggingContext(LoggingContext):
|
39
|
+
def __init__(self, *infos: LoggingContextInfo) -> None:
|
40
|
+
self._infos: ta.Dict[ta.Type[LoggingContextInfo], LoggingContextInfo] = {type(i): i for i in infos}
|
64
41
|
|
65
|
-
|
66
|
-
|
67
|
-
raise NotImplementedError
|
42
|
+
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
43
|
+
return self._infos.get(ty)
|
68
44
|
|
69
|
-
#
|
70
45
|
|
71
|
-
|
72
|
-
def thread(self) -> ta.Optional[LoggingThreadInfo]:
|
73
|
-
raise NotImplementedError
|
46
|
+
##
|
74
47
|
|
75
|
-
@abc.abstractmethod
|
76
|
-
def process(self) -> ta.Optional[LoggingProcessInfo]:
|
77
|
-
raise NotImplementedError
|
78
48
|
|
49
|
+
class CaptureLoggingContext(LoggingContext, Abstract):
|
79
50
|
@abc.abstractmethod
|
80
|
-
def
|
81
|
-
|
51
|
+
def set_basic(
|
52
|
+
self,
|
53
|
+
name: str,
|
82
54
|
|
83
|
-
|
84
|
-
|
55
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
56
|
+
args: tuple,
|
57
|
+
) -> 'CaptureLoggingContext':
|
85
58
|
raise NotImplementedError
|
86
59
|
|
60
|
+
#
|
87
61
|
|
88
|
-
##
|
89
|
-
|
90
|
-
|
91
|
-
class CaptureLoggingContext(LoggingContext, Abstract):
|
92
62
|
class AlreadyCapturedError(Exception):
|
93
63
|
pass
|
94
64
|
|
@@ -119,80 +89,50 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
119
89
|
|
120
90
|
exc_info: LoggingExcInfoArg = False,
|
121
91
|
|
122
|
-
caller: ta.Union[
|
92
|
+
caller: ta.Union[LoggingContextInfos.Caller, ta.Type[NOT_SET], None] = NOT_SET,
|
123
93
|
stack_offset: int = 0,
|
124
94
|
stack_info: bool = False,
|
125
95
|
) -> None:
|
126
|
-
|
127
|
-
|
128
|
-
#
|
96
|
+
# TODO: Name, Msg, Extra
|
129
97
|
|
130
98
|
if time_ns is None:
|
131
99
|
time_ns = time.time_ns()
|
132
|
-
self._time_ns: int = time_ns
|
133
|
-
|
134
|
-
#
|
135
|
-
|
136
|
-
if exc_info is True:
|
137
|
-
sys_exc_info = sys.exc_info()
|
138
|
-
if sys_exc_info[0] is not None:
|
139
|
-
exc_info = sys_exc_info
|
140
|
-
else:
|
141
|
-
exc_info = None
|
142
|
-
elif exc_info is False:
|
143
|
-
exc_info = None
|
144
|
-
|
145
|
-
if exc_info is not None:
|
146
|
-
self._exc_info: ta.Optional[LoggingExcInfo] = exc_info
|
147
|
-
if isinstance(exc_info, BaseException):
|
148
|
-
self._exc_info_tuple: ta.Optional[LoggingExcInfoTuple] = (type(exc_info), exc_info, exc_info.__traceback__) # noqa
|
149
|
-
else:
|
150
|
-
self._exc_info_tuple = exc_info
|
151
100
|
|
152
|
-
|
101
|
+
self._infos: ta.Dict[ta.Type[LoggingContextInfo], LoggingContextInfo] = {}
|
102
|
+
self._set_info(
|
103
|
+
LoggingContextInfos.Level.build(level),
|
104
|
+
LoggingContextInfos.Time.build(time_ns),
|
105
|
+
LoggingContextInfos.Exc.build(exc_info),
|
106
|
+
)
|
153
107
|
|
154
108
|
if caller is not CaptureLoggingContextImpl.NOT_SET:
|
155
|
-
self.
|
109
|
+
self._infos[LoggingContextInfos.Caller] = caller
|
156
110
|
else:
|
157
111
|
self._stack_offset = stack_offset
|
158
112
|
self._stack_info = stack_info
|
159
113
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
return self
|
165
|
-
|
166
|
-
#
|
167
|
-
|
168
|
-
@property
|
169
|
-
def time_ns(self) -> int:
|
170
|
-
return self._time_ns
|
171
|
-
|
172
|
-
_times: LoggingTimeFields
|
173
|
-
|
174
|
-
@property
|
175
|
-
def times(self) -> LoggingTimeFields:
|
176
|
-
try:
|
177
|
-
return self._times
|
178
|
-
except AttributeError:
|
179
|
-
pass
|
180
|
-
|
181
|
-
times = self._times = LoggingTimeFields.build(self.time_ns)
|
182
|
-
return times
|
114
|
+
def _set_info(self, *infos: ta.Optional[LoggingContextInfo]) -> 'CaptureLoggingContextImpl':
|
115
|
+
for info in infos:
|
116
|
+
if info is not None:
|
117
|
+
self._infos[type(info)] = info
|
118
|
+
return self
|
183
119
|
|
184
|
-
|
120
|
+
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
121
|
+
return self._infos.get(ty)
|
185
122
|
|
186
|
-
|
187
|
-
_exc_info_tuple: ta.Optional[LoggingExcInfoTuple] = None
|
123
|
+
##
|
188
124
|
|
189
|
-
|
190
|
-
|
191
|
-
|
125
|
+
def set_basic(
|
126
|
+
self,
|
127
|
+
name: str,
|
192
128
|
|
193
|
-
|
194
|
-
|
195
|
-
|
129
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
130
|
+
args: tuple,
|
131
|
+
) -> 'CaptureLoggingContextImpl':
|
132
|
+
return self._set_info(
|
133
|
+
LoggingContextInfos.Name(name),
|
134
|
+
LoggingContextInfos.Msg.build(msg, *args),
|
135
|
+
)
|
196
136
|
|
197
137
|
##
|
198
138
|
|
@@ -206,71 +146,25 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
206
146
|
|
207
147
|
_has_captured: bool = False
|
208
148
|
|
209
|
-
_caller: ta.Optional[LoggingCaller]
|
210
|
-
_source_file: ta.Optional[LoggingSourceFileInfo]
|
211
|
-
|
212
|
-
_thread: ta.Optional[LoggingThreadInfo]
|
213
|
-
_process: ta.Optional[LoggingProcessInfo]
|
214
|
-
_multiprocessing: ta.Optional[LoggingMultiprocessingInfo]
|
215
|
-
_asyncio_task: ta.Optional[LoggingAsyncioTaskInfo]
|
216
|
-
|
217
149
|
def capture(self) -> None:
|
218
150
|
if self._has_captured:
|
219
151
|
raise CaptureLoggingContextImpl.AlreadyCapturedError
|
220
152
|
self._has_captured = True
|
221
153
|
|
222
|
-
if not
|
223
|
-
self.
|
154
|
+
if LoggingContextInfos.Caller not in self._infos:
|
155
|
+
self._set_info(LoggingContextInfos.Caller.build(
|
224
156
|
self._stack_offset + 1,
|
225
157
|
stack_info=self._stack_info,
|
226
|
-
)
|
227
|
-
|
228
|
-
if (caller := self.
|
229
|
-
self.
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
self.
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
def caller(self) -> ta.Optional[LoggingCaller]:
|
241
|
-
try:
|
242
|
-
return self._caller
|
243
|
-
except AttributeError:
|
244
|
-
raise CaptureLoggingContext.NotCapturedError from None
|
245
|
-
|
246
|
-
def source_file(self) -> ta.Optional[LoggingSourceFileInfo]:
|
247
|
-
try:
|
248
|
-
return self._source_file
|
249
|
-
except AttributeError:
|
250
|
-
raise CaptureLoggingContext.NotCapturedError from None
|
251
|
-
|
252
|
-
#
|
253
|
-
|
254
|
-
def thread(self) -> ta.Optional[LoggingThreadInfo]:
|
255
|
-
try:
|
256
|
-
return self._thread
|
257
|
-
except AttributeError:
|
258
|
-
raise CaptureLoggingContext.NotCapturedError from None
|
259
|
-
|
260
|
-
def process(self) -> ta.Optional[LoggingProcessInfo]:
|
261
|
-
try:
|
262
|
-
return self._process
|
263
|
-
except AttributeError:
|
264
|
-
raise CaptureLoggingContext.NotCapturedError from None
|
265
|
-
|
266
|
-
def multiprocessing(self) -> ta.Optional[LoggingMultiprocessingInfo]:
|
267
|
-
try:
|
268
|
-
return self._multiprocessing
|
269
|
-
except AttributeError:
|
270
|
-
raise CaptureLoggingContext.NotCapturedError from None
|
271
|
-
|
272
|
-
def asyncio_task(self) -> ta.Optional[LoggingAsyncioTaskInfo]:
|
273
|
-
try:
|
274
|
-
return self._asyncio_task
|
275
|
-
except AttributeError:
|
276
|
-
raise CaptureLoggingContext.NotCapturedError from None
|
158
|
+
))
|
159
|
+
|
160
|
+
if (caller := self[LoggingContextInfos.Caller]) is not None:
|
161
|
+
self._set_info(LoggingContextInfos.SourceFile.build(
|
162
|
+
caller.file_path,
|
163
|
+
))
|
164
|
+
|
165
|
+
self._set_info(
|
166
|
+
LoggingContextInfos.Thread.build(),
|
167
|
+
LoggingContextInfos.Process.build(),
|
168
|
+
LoggingContextInfos.Multiprocessing.build(),
|
169
|
+
LoggingContextInfos.AsyncioTask.build(),
|
170
|
+
)
|