omlish 0.0.0.dev426__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/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/protocols.py +7 -7
- omlish/logs/std/adapters.py +9 -5
- omlish/logs/std/records.py +26 -11
- omlish/logs/times.py +2 -1
- omlish/manifests/loading.py +6 -0
- omlish/sockets/server/server.py +1 -1
- {omlish-0.0.0.dev426.dist-info → omlish-0.0.0.dev427.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev426.dist-info → omlish-0.0.0.dev427.dist-info}/RECORD +17 -16
- {omlish-0.0.0.dev426.dist-info → omlish-0.0.0.dev427.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev426.dist-info → omlish-0.0.0.dev427.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev426.dist-info → omlish-0.0.0.dev427.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev426.dist-info → omlish-0.0.0.dev427.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/logs/base.py
CHANGED
@@ -1,229 +1,215 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007 UP045 UP046
|
2
2
|
# @omlish-lite
|
3
3
|
import abc
|
4
|
-
import sys
|
5
|
-
import time
|
6
|
-
import types
|
7
4
|
import typing as ta
|
8
5
|
|
9
6
|
from ..lite.abstract import Abstract
|
10
|
-
from .
|
11
|
-
from .
|
12
|
-
from .
|
13
|
-
from .
|
14
|
-
from .infos import LoggingSourceFileInfo
|
15
|
-
from .infos import LoggingThreadInfo
|
7
|
+
from .contexts import CaptureLoggingContext
|
8
|
+
from .contexts import CaptureLoggingContextImpl
|
9
|
+
from .contexts import LoggingExcInfoArg
|
10
|
+
from .levels import LogLevel
|
16
11
|
from .levels import NamedLogLevel
|
17
|
-
from .times import LoggingTimeFields
|
18
12
|
|
19
13
|
|
20
14
|
T = ta.TypeVar('T')
|
21
15
|
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
LoggingExcInfoTuple = ta.Tuple[ta.Type[BaseException], BaseException, ta.Optional[types.TracebackType]] # ta.TypeAlias
|
26
|
-
LoggingExcInfo = ta.Union[BaseException, LoggingExcInfoTuple] # ta.TypeAlias
|
27
|
-
LoggingExcInfoArg = ta.Union[LoggingExcInfo, bool, None] # ta.TypeAlias
|
17
|
+
LoggingMsgFn = ta.Callable[[], ta.Union[str, tuple]] # ta.TypeAlias
|
28
18
|
|
29
19
|
|
30
20
|
##
|
31
21
|
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
|
23
|
+
class AnyLogger(Abstract, ta.Generic[T]):
|
24
|
+
def is_enabled_for(self, level: LogLevel) -> bool:
|
25
|
+
return self.get_effective_level() >= level
|
36
26
|
|
37
|
-
|
27
|
+
@abc.abstractmethod
|
28
|
+
def get_effective_level(self) -> LogLevel:
|
29
|
+
raise NotImplementedError
|
38
30
|
|
39
|
-
|
40
|
-
exc_info_tuple: ta.Optional[LoggingExcInfoTuple] = None
|
31
|
+
#
|
41
32
|
|
42
33
|
@ta.final
|
43
|
-
|
44
|
-
|
45
|
-
raise TypeError
|
46
|
-
|
47
|
-
#
|
34
|
+
def isEnabledFor(self, level: LogLevel) -> bool: # noqa
|
35
|
+
return self.is_enabled_for(level)
|
48
36
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
*,
|
53
|
-
time_ns: ta.Optional[int] = None,
|
37
|
+
@ta.final
|
38
|
+
def getEffectiveLevel(self) -> LogLevel: # noqa
|
39
|
+
return self.get_effective_level()
|
54
40
|
|
55
|
-
|
41
|
+
##
|
56
42
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
) -> None:
|
61
|
-
self.level = level if level.__class__ is NamedLogLevel else NamedLogLevel(level) # type: ignore[assignment]
|
43
|
+
@ta.overload
|
44
|
+
def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
45
|
+
...
|
62
46
|
|
63
|
-
|
47
|
+
@ta.overload
|
48
|
+
def log(self, level: LogLevel, msg: ta.Tuple[ta.Any, ...], **kwargs: ta.Any) -> T:
|
49
|
+
...
|
64
50
|
|
65
|
-
|
66
|
-
|
67
|
-
|
51
|
+
@ta.overload
|
52
|
+
def log(self, level: LogLevel, msg_fn: LoggingMsgFn, **kwargs: ta.Any) -> T:
|
53
|
+
...
|
68
54
|
|
69
|
-
|
55
|
+
@ta.final
|
56
|
+
def log(self, level: LogLevel, *args, **kwargs):
|
57
|
+
return self._log(CaptureLoggingContextImpl(level, stack_offset=1), *args, **kwargs)
|
70
58
|
|
71
|
-
|
72
|
-
sys_exc_info = sys.exc_info()
|
73
|
-
if sys_exc_info[0] is not None:
|
74
|
-
exc_info = sys_exc_info
|
75
|
-
else:
|
76
|
-
exc_info = None
|
77
|
-
elif exc_info is False:
|
78
|
-
exc_info = None
|
79
|
-
|
80
|
-
if exc_info is not None:
|
81
|
-
self.exc_info = exc_info
|
82
|
-
if isinstance(exc_info, BaseException):
|
83
|
-
self.exc_info_tuple = (type(exc_info), exc_info, exc_info.__traceback__)
|
84
|
-
else:
|
85
|
-
self.exc_info_tuple = exc_info
|
59
|
+
#
|
86
60
|
|
87
|
-
|
61
|
+
@ta.overload
|
62
|
+
def debug(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
63
|
+
...
|
88
64
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
self._stack_offset = stack_offset
|
93
|
-
self._stack_info = stack_info
|
65
|
+
@ta.overload
|
66
|
+
def debug(self, msg: ta.Tuple[ta.Any, ...], **kwargs: ta.Any) -> T:
|
67
|
+
...
|
94
68
|
|
95
|
-
|
69
|
+
@ta.overload
|
70
|
+
def debug(self, msg_fn: LoggingMsgFn, **kwargs: ta.Any) -> T:
|
71
|
+
...
|
96
72
|
|
97
|
-
|
98
|
-
|
99
|
-
self.
|
100
|
-
self.asyncio_task = LoggingAsyncioTaskInfo.build()
|
73
|
+
@ta.final
|
74
|
+
def debug(self, *args, **kwargs):
|
75
|
+
return self._log(CaptureLoggingContextImpl(NamedLogLevel.DEBUG, stack_offset=1), *args, **kwargs)
|
101
76
|
|
102
77
|
#
|
103
78
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
def times(self) -> LoggingTimeFields:
|
108
|
-
try:
|
109
|
-
return self._times
|
110
|
-
except AttributeError:
|
111
|
-
pass
|
112
|
-
|
113
|
-
times = self._times = LoggingTimeFields.build(self.time_ns)
|
114
|
-
return times
|
115
|
-
|
116
|
-
#
|
79
|
+
@ta.overload
|
80
|
+
def info(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
81
|
+
...
|
117
82
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
return self
|
83
|
+
@ta.overload
|
84
|
+
def info(self, msg: ta.Tuple[ta.Any, ...], **kwargs: ta.Any) -> T:
|
85
|
+
...
|
122
86
|
|
123
|
-
|
87
|
+
@ta.overload
|
88
|
+
def info(self, msg_fn: LoggingMsgFn, **kwargs: ta.Any) -> T:
|
89
|
+
...
|
124
90
|
|
125
|
-
|
126
|
-
|
91
|
+
@ta.final
|
92
|
+
def info(self, *args, **kwargs):
|
93
|
+
return self._log(CaptureLoggingContextImpl(NamedLogLevel.INFO, stack_offset=1), *args, **kwargs)
|
127
94
|
|
128
|
-
|
129
|
-
return self._caller
|
130
|
-
except AttributeError:
|
131
|
-
pass
|
95
|
+
#
|
132
96
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
)
|
137
|
-
return caller
|
97
|
+
@ta.overload
|
98
|
+
def warning(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
99
|
+
...
|
138
100
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
except AttributeError:
|
143
|
-
return None
|
101
|
+
@ta.overload
|
102
|
+
def warning(self, msg: ta.Tuple[ta.Any, ...], **kwargs: ta.Any) -> T:
|
103
|
+
...
|
144
104
|
|
145
|
-
|
105
|
+
@ta.overload
|
106
|
+
def warning(self, msg_fn: LoggingMsgFn, **kwargs: ta.Any) -> T:
|
107
|
+
...
|
146
108
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
except AttributeError:
|
151
|
-
pass
|
109
|
+
@ta.final
|
110
|
+
def warning(self, *args, **kwargs):
|
111
|
+
return self._log(CaptureLoggingContextImpl(NamedLogLevel.WARNING, stack_offset=1), *args, **kwargs)
|
152
112
|
|
153
|
-
|
154
|
-
return None
|
113
|
+
#
|
155
114
|
|
156
|
-
|
157
|
-
|
115
|
+
@ta.overload
|
116
|
+
def error(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
117
|
+
...
|
158
118
|
|
119
|
+
@ta.overload
|
120
|
+
def error(self, msg: ta.Tuple[ta.Any, ...], **kwargs: ta.Any) -> T:
|
121
|
+
...
|
159
122
|
|
160
|
-
|
123
|
+
@ta.overload
|
124
|
+
def error(self, msg_fn: LoggingMsgFn, **kwargs: ta.Any) -> T:
|
125
|
+
...
|
161
126
|
|
127
|
+
@ta.final
|
128
|
+
def error(self, *args, **kwargs):
|
129
|
+
return self._log(CaptureLoggingContextImpl(NamedLogLevel.ERROR, stack_offset=1), *args, **kwargs)
|
162
130
|
|
163
|
-
|
164
|
-
def is_enabled_for(self, level: LogLevel) -> bool:
|
165
|
-
return self.get_effective_level() >= level
|
131
|
+
#
|
166
132
|
|
167
|
-
@
|
168
|
-
def
|
169
|
-
|
133
|
+
@ta.overload
|
134
|
+
def exception(self, msg: str, *args: ta.Any, exc_info: LoggingExcInfoArg = True, **kwargs: ta.Any) -> T:
|
135
|
+
...
|
170
136
|
|
171
|
-
|
137
|
+
@ta.overload
|
138
|
+
def exception(self, msg: ta.Tuple[ta.Any, ...], *, exc_info: LoggingExcInfoArg = True, **kwargs: ta.Any) -> T:
|
139
|
+
...
|
172
140
|
|
173
|
-
@ta.
|
174
|
-
def
|
175
|
-
|
141
|
+
@ta.overload
|
142
|
+
def exception(self, msg_fn: LoggingMsgFn, *, exc_info: LoggingExcInfoArg = True, **kwargs: ta.Any) -> T:
|
143
|
+
...
|
176
144
|
|
177
145
|
@ta.final
|
178
|
-
def
|
179
|
-
return self.
|
146
|
+
def exception(self, *args, exc_info: LoggingExcInfoArg = True, **kwargs):
|
147
|
+
return self._log(CaptureLoggingContextImpl(NamedLogLevel.ERROR, exc_info=exc_info, stack_offset=1), *args, **kwargs) # noqa
|
180
148
|
|
181
149
|
#
|
182
150
|
|
183
|
-
@ta.
|
184
|
-
def
|
185
|
-
|
151
|
+
@ta.overload
|
152
|
+
def critical(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
153
|
+
...
|
186
154
|
|
187
|
-
@ta.
|
188
|
-
def
|
189
|
-
|
155
|
+
@ta.overload
|
156
|
+
def critical(self, msg: ta.Tuple[ta.Any, ...], **kwargs: ta.Any) -> T:
|
157
|
+
...
|
190
158
|
|
191
|
-
@ta.
|
192
|
-
def
|
193
|
-
|
159
|
+
@ta.overload
|
160
|
+
def critical(self, msg_fn: LoggingMsgFn, **kwargs: ta.Any) -> T:
|
161
|
+
...
|
194
162
|
|
195
163
|
@ta.final
|
196
|
-
def
|
197
|
-
return self._log(
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
164
|
+
def critical(self, *args, **kwargs):
|
165
|
+
return self._log(CaptureLoggingContextImpl(NamedLogLevel.CRITICAL, stack_offset=1), *args, **kwargs)
|
166
|
+
|
167
|
+
##
|
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)
|
202
184
|
|
203
|
-
|
204
|
-
|
205
|
-
|
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 '', ()
|
206
192
|
|
207
|
-
|
208
|
-
|
209
|
-
return self._log(LoggingContext(level, stack_offset=1), msg, *args, **kwargs)
|
193
|
+
elif isinstance(msg, str):
|
194
|
+
return msg, args
|
210
195
|
|
211
|
-
|
196
|
+
else:
|
197
|
+
raise TypeError(msg)
|
212
198
|
|
213
199
|
@abc.abstractmethod
|
214
|
-
def _log(self, ctx:
|
200
|
+
def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> T: # noqa
|
215
201
|
raise NotImplementedError
|
216
202
|
|
217
203
|
|
218
204
|
class Logger(AnyLogger[None], Abstract):
|
219
205
|
@abc.abstractmethod
|
220
|
-
def _log(self, ctx:
|
206
|
+
def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> None: # noqa
|
221
207
|
raise NotImplementedError
|
222
208
|
|
223
209
|
|
224
210
|
class AsyncLogger(AnyLogger[ta.Awaitable[None]], Abstract):
|
225
211
|
@abc.abstractmethod
|
226
|
-
def _log(self, ctx:
|
212
|
+
def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> ta.Awaitable[None]: # noqa
|
227
213
|
raise NotImplementedError
|
228
214
|
|
229
215
|
|
@@ -238,11 +224,11 @@ class AnyNopLogger(AnyLogger[T], Abstract):
|
|
238
224
|
|
239
225
|
@ta.final
|
240
226
|
class NopLogger(AnyNopLogger[None], Logger):
|
241
|
-
def _log(self, ctx:
|
227
|
+
def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> None: # noqa
|
242
228
|
pass
|
243
229
|
|
244
230
|
|
245
231
|
@ta.final
|
246
232
|
class AsyncNopLogger(AnyNopLogger[ta.Awaitable[None]], AsyncLogger):
|
247
|
-
async def _log(self, ctx:
|
233
|
+
async def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> None: # noqa
|
248
234
|
pass
|
omlish/logs/callers.py
CHANGED
@@ -7,11 +7,13 @@ import traceback
|
|
7
7
|
import types
|
8
8
|
import typing as ta
|
9
9
|
|
10
|
+
from .infos import LoggingContextInfo
|
11
|
+
|
10
12
|
|
11
13
|
##
|
12
14
|
|
13
15
|
|
14
|
-
class LoggingCaller(ta.NamedTuple):
|
16
|
+
class LoggingCaller(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
15
17
|
file_path: str
|
16
18
|
line_no: int
|
17
19
|
name: str
|
@@ -57,8 +59,6 @@ class LoggingCaller(ta.NamedTuple):
|
|
57
59
|
sinfo = None
|
58
60
|
if stack_info:
|
59
61
|
sio = io.StringIO()
|
60
|
-
# In stdlib, but done elsewhere here:
|
61
|
-
# sio.write('Stack (most recent call last):\n')
|
62
62
|
traceback.print_stack(f, file=sio)
|
63
63
|
sinfo = sio.getvalue()
|
64
64
|
sio.close()
|
omlish/logs/contexts.py
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007 UP045 UP046
|
2
|
+
# @omlish-lite
|
3
|
+
import abc
|
4
|
+
import sys
|
5
|
+
import time
|
6
|
+
import types
|
7
|
+
import typing as ta
|
8
|
+
|
9
|
+
from ..lite.abstract import Abstract
|
10
|
+
from .callers import LoggingCaller
|
11
|
+
from .infos import LoggingAsyncioTaskInfo
|
12
|
+
from .infos import LoggingMultiprocessingInfo
|
13
|
+
from .infos import LoggingProcessInfo
|
14
|
+
from .infos import LoggingSourceFileInfo
|
15
|
+
from .infos import LoggingThreadInfo
|
16
|
+
from .levels import LogLevel
|
17
|
+
from .levels import NamedLogLevel
|
18
|
+
from .times import LoggingTimeFields
|
19
|
+
|
20
|
+
|
21
|
+
LoggingExcInfoTuple = ta.Tuple[ta.Type[BaseException], BaseException, ta.Optional[types.TracebackType]] # ta.TypeAlias
|
22
|
+
LoggingExcInfo = ta.Union[BaseException, LoggingExcInfoTuple] # ta.TypeAlias
|
23
|
+
LoggingExcInfoArg = ta.Union[LoggingExcInfo, bool, None] # ta.TypeAlias
|
24
|
+
|
25
|
+
|
26
|
+
##
|
27
|
+
|
28
|
+
|
29
|
+
class LoggingContext(Abstract):
|
30
|
+
@property
|
31
|
+
@abc.abstractmethod
|
32
|
+
def level(self) -> NamedLogLevel:
|
33
|
+
raise NotImplementedError
|
34
|
+
|
35
|
+
#
|
36
|
+
|
37
|
+
@property
|
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
|
53
|
+
|
54
|
+
@property
|
55
|
+
@abc.abstractmethod
|
56
|
+
def exc_info_tuple(self) -> ta.Optional[LoggingExcInfoTuple]:
|
57
|
+
raise NotImplementedError
|
58
|
+
|
59
|
+
#
|
60
|
+
|
61
|
+
@abc.abstractmethod
|
62
|
+
def caller(self) -> ta.Optional[LoggingCaller]:
|
63
|
+
raise NotImplementedError
|
64
|
+
|
65
|
+
@abc.abstractmethod
|
66
|
+
def source_file(self) -> ta.Optional[LoggingSourceFileInfo]:
|
67
|
+
raise NotImplementedError
|
68
|
+
|
69
|
+
#
|
70
|
+
|
71
|
+
@abc.abstractmethod
|
72
|
+
def thread(self) -> ta.Optional[LoggingThreadInfo]:
|
73
|
+
raise NotImplementedError
|
74
|
+
|
75
|
+
@abc.abstractmethod
|
76
|
+
def process(self) -> ta.Optional[LoggingProcessInfo]:
|
77
|
+
raise NotImplementedError
|
78
|
+
|
79
|
+
@abc.abstractmethod
|
80
|
+
def multiprocessing(self) -> ta.Optional[LoggingMultiprocessingInfo]:
|
81
|
+
raise NotImplementedError
|
82
|
+
|
83
|
+
@abc.abstractmethod
|
84
|
+
def asyncio_task(self) -> ta.Optional[LoggingAsyncioTaskInfo]:
|
85
|
+
raise NotImplementedError
|
86
|
+
|
87
|
+
|
88
|
+
##
|
89
|
+
|
90
|
+
|
91
|
+
class CaptureLoggingContext(LoggingContext, Abstract):
|
92
|
+
@abc.abstractmethod
|
93
|
+
def capture(self) -> None:
|
94
|
+
"""Must be cooperatively called only from the expected locations."""
|
95
|
+
|
96
|
+
raise NotImplementedError
|
97
|
+
|
98
|
+
|
99
|
+
@ta.final
|
100
|
+
class CaptureLoggingContextImpl(CaptureLoggingContext):
|
101
|
+
@ta.final
|
102
|
+
class NOT_SET: # noqa
|
103
|
+
def __new__(cls, *args, **kwargs): # noqa
|
104
|
+
raise TypeError
|
105
|
+
|
106
|
+
#
|
107
|
+
|
108
|
+
def __init__(
|
109
|
+
self,
|
110
|
+
level: LogLevel,
|
111
|
+
*,
|
112
|
+
time_ns: ta.Optional[int] = None,
|
113
|
+
|
114
|
+
exc_info: LoggingExcInfoArg = False,
|
115
|
+
|
116
|
+
caller: ta.Union[LoggingCaller, ta.Type[NOT_SET], None] = NOT_SET,
|
117
|
+
stack_offset: int = 0,
|
118
|
+
stack_info: bool = False,
|
119
|
+
) -> None:
|
120
|
+
self._level: NamedLogLevel = level if level.__class__ is NamedLogLevel else NamedLogLevel(level) # type: ignore[assignment] # noqa
|
121
|
+
|
122
|
+
#
|
123
|
+
|
124
|
+
if time_ns is None:
|
125
|
+
time_ns = time.time_ns()
|
126
|
+
self._time_ns: int = time_ns
|
127
|
+
|
128
|
+
#
|
129
|
+
|
130
|
+
if exc_info is True:
|
131
|
+
sys_exc_info = sys.exc_info()
|
132
|
+
if sys_exc_info[0] is not None:
|
133
|
+
exc_info = sys_exc_info
|
134
|
+
else:
|
135
|
+
exc_info = None
|
136
|
+
elif exc_info is False:
|
137
|
+
exc_info = None
|
138
|
+
|
139
|
+
if exc_info is not None:
|
140
|
+
self._exc_info: ta.Optional[LoggingExcInfo] = exc_info
|
141
|
+
if isinstance(exc_info, BaseException):
|
142
|
+
self._exc_info_tuple: ta.Optional[LoggingExcInfoTuple] = (type(exc_info), exc_info, exc_info.__traceback__) # noqa
|
143
|
+
else:
|
144
|
+
self._exc_info_tuple = exc_info
|
145
|
+
else:
|
146
|
+
self._exc_info = None
|
147
|
+
self._exc_info_tuple = None
|
148
|
+
|
149
|
+
#
|
150
|
+
|
151
|
+
if caller is not CaptureLoggingContextImpl.NOT_SET:
|
152
|
+
self._caller = caller # type: ignore[assignment]
|
153
|
+
else:
|
154
|
+
self._stack_offset = stack_offset
|
155
|
+
self._stack_info = stack_info
|
156
|
+
|
157
|
+
#
|
158
|
+
|
159
|
+
self._thread = LoggingThreadInfo.build()
|
160
|
+
self._process = LoggingProcessInfo.build()
|
161
|
+
self._multiprocessing = LoggingMultiprocessingInfo.build()
|
162
|
+
self._asyncio_task = LoggingAsyncioTaskInfo.build()
|
163
|
+
|
164
|
+
#
|
165
|
+
|
166
|
+
@property
|
167
|
+
def level(self) -> NamedLogLevel:
|
168
|
+
return self._level
|
169
|
+
|
170
|
+
#
|
171
|
+
|
172
|
+
@property
|
173
|
+
def time_ns(self) -> int:
|
174
|
+
return self._time_ns
|
175
|
+
|
176
|
+
_times: LoggingTimeFields
|
177
|
+
|
178
|
+
@property
|
179
|
+
def times(self) -> LoggingTimeFields:
|
180
|
+
try:
|
181
|
+
return self._times
|
182
|
+
except AttributeError:
|
183
|
+
pass
|
184
|
+
|
185
|
+
times = self._times = LoggingTimeFields.build(self.time_ns)
|
186
|
+
return times
|
187
|
+
|
188
|
+
@property
|
189
|
+
def exc_info(self) -> ta.Optional[LoggingExcInfo]:
|
190
|
+
return self._exc_info
|
191
|
+
|
192
|
+
@property
|
193
|
+
def exc_info_tuple(self) -> ta.Optional[LoggingExcInfoTuple]:
|
194
|
+
return self._exc_info_tuple
|
195
|
+
|
196
|
+
#
|
197
|
+
|
198
|
+
def inc_stack_offset(self, ofs: int = 1) -> 'LoggingContext':
|
199
|
+
if hasattr(self, '_stack_offset'):
|
200
|
+
self._stack_offset += ofs
|
201
|
+
return self
|
202
|
+
|
203
|
+
_caller: ta.Optional[LoggingCaller]
|
204
|
+
|
205
|
+
def capture(self) -> None:
|
206
|
+
"""Must be cooperatively called only from the exact configured _stack_offset."""
|
207
|
+
|
208
|
+
try:
|
209
|
+
self._caller # noqa
|
210
|
+
except AttributeError:
|
211
|
+
pass
|
212
|
+
|
213
|
+
self._caller = LoggingCaller.find(
|
214
|
+
self._stack_offset + 1,
|
215
|
+
stack_info=self._stack_info,
|
216
|
+
)
|
217
|
+
|
218
|
+
def caller(self) -> ta.Optional[LoggingCaller]:
|
219
|
+
try:
|
220
|
+
return self._caller
|
221
|
+
except AttributeError:
|
222
|
+
return None
|
223
|
+
|
224
|
+
_source_file: ta.Optional[LoggingSourceFileInfo]
|
225
|
+
|
226
|
+
def source_file(self) -> ta.Optional[LoggingSourceFileInfo]:
|
227
|
+
try:
|
228
|
+
return self._source_file
|
229
|
+
except AttributeError:
|
230
|
+
pass
|
231
|
+
|
232
|
+
if (caller := self.caller()) is None:
|
233
|
+
return None
|
234
|
+
|
235
|
+
src_file = self._source_file = LoggingSourceFileInfo.build(caller.file_path)
|
236
|
+
return src_file
|
237
|
+
|
238
|
+
#
|
239
|
+
|
240
|
+
def thread(self) -> ta.Optional[LoggingThreadInfo]:
|
241
|
+
return self._thread
|
242
|
+
|
243
|
+
def process(self) -> ta.Optional[LoggingProcessInfo]:
|
244
|
+
return self._process
|
245
|
+
|
246
|
+
def multiprocessing(self) -> ta.Optional[LoggingMultiprocessingInfo]:
|
247
|
+
return self._multiprocessing
|
248
|
+
|
249
|
+
def asyncio_task(self) -> ta.Optional[LoggingAsyncioTaskInfo]:
|
250
|
+
return self._asyncio_task
|
omlish/logs/infos.py
CHANGED
@@ -9,8 +9,19 @@ import typing as ta
|
|
9
9
|
##
|
10
10
|
|
11
11
|
|
12
|
+
class _LoggingContextInfo:
|
13
|
+
def __mro_entries__(self, bases):
|
14
|
+
return ()
|
15
|
+
|
16
|
+
|
17
|
+
LoggingContextInfo: type = ta.cast(ta.Any, _LoggingContextInfo())
|
18
|
+
|
19
|
+
|
20
|
+
##
|
21
|
+
|
22
|
+
|
12
23
|
@ta.final
|
13
|
-
class LoggingSourceFileInfo(ta.NamedTuple):
|
24
|
+
class LoggingSourceFileInfo(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
14
25
|
file_name: str
|
15
26
|
module: str
|
16
27
|
|
@@ -36,7 +47,7 @@ class LoggingSourceFileInfo(ta.NamedTuple):
|
|
36
47
|
|
37
48
|
|
38
49
|
@ta.final
|
39
|
-
class LoggingThreadInfo(ta.NamedTuple):
|
50
|
+
class LoggingThreadInfo(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
40
51
|
ident: int
|
41
52
|
native_id: ta.Optional[int]
|
42
53
|
name: str
|
@@ -54,7 +65,7 @@ class LoggingThreadInfo(ta.NamedTuple):
|
|
54
65
|
|
55
66
|
|
56
67
|
@ta.final
|
57
|
-
class LoggingProcessInfo(ta.NamedTuple):
|
68
|
+
class LoggingProcessInfo(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
58
69
|
pid: int
|
59
70
|
|
60
71
|
@classmethod
|
@@ -68,7 +79,7 @@ class LoggingProcessInfo(ta.NamedTuple):
|
|
68
79
|
|
69
80
|
|
70
81
|
@ta.final
|
71
|
-
class LoggingMultiprocessingInfo(ta.NamedTuple):
|
82
|
+
class LoggingMultiprocessingInfo(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
72
83
|
process_name: str
|
73
84
|
|
74
85
|
@classmethod
|
@@ -86,7 +97,7 @@ class LoggingMultiprocessingInfo(ta.NamedTuple):
|
|
86
97
|
|
87
98
|
|
88
99
|
@ta.final
|
89
|
-
class LoggingAsyncioTaskInfo(ta.NamedTuple):
|
100
|
+
class LoggingAsyncioTaskInfo(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
90
101
|
name: str
|
91
102
|
|
92
103
|
@classmethod
|
omlish/logs/protocols.py
CHANGED
@@ -16,16 +16,16 @@ class LoggerLike(ta.Protocol):
|
|
16
16
|
|
17
17
|
#
|
18
18
|
|
19
|
-
def
|
19
|
+
def log(self, level: LogLevel, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
20
20
|
|
21
|
-
def
|
21
|
+
def debug(self, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
22
22
|
|
23
|
-
def
|
23
|
+
def info(self, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
24
24
|
|
25
|
-
def
|
25
|
+
def warning(self, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
26
26
|
|
27
|
-
def
|
27
|
+
def error(self, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
28
28
|
|
29
|
-
def
|
29
|
+
def exception(self, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
30
30
|
|
31
|
-
def
|
31
|
+
def critical(self, msg: str, /, *args: ta.Any, **kwargs: ta.Any) -> None: ... # noqa
|
omlish/logs/std/adapters.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# ruff: noqa: UP007
|
1
2
|
# @omlish-lite
|
2
3
|
import logging
|
3
4
|
import typing as ta
|
4
5
|
|
5
6
|
from ..base import Logger
|
6
|
-
from ..base import
|
7
|
-
from ..
|
7
|
+
from ..base import LoggingMsgFn
|
8
|
+
from ..contexts import CaptureLoggingContext
|
9
|
+
from ..levels import LogLevel
|
8
10
|
from .records import LoggingContextLogRecord
|
9
11
|
|
10
12
|
|
@@ -24,15 +26,17 @@ class StdLogger(Logger):
|
|
24
26
|
def get_effective_level(self) -> LogLevel:
|
25
27
|
return self._std.getEffectiveLevel()
|
26
28
|
|
27
|
-
def _log(self, ctx:
|
29
|
+
def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any) -> None:
|
28
30
|
if not self.is_enabled_for(ctx.level):
|
29
31
|
return
|
30
32
|
|
31
|
-
ctx.
|
33
|
+
ctx.capture()
|
34
|
+
|
35
|
+
ms, args = self._prepare_msg_args(msg, *args)
|
32
36
|
|
33
37
|
rec = LoggingContextLogRecord(
|
34
38
|
name=self._std.name,
|
35
|
-
msg=
|
39
|
+
msg=ms,
|
36
40
|
args=args,
|
37
41
|
|
38
42
|
_logging_context=ctx,
|
omlish/logs/std/records.py
CHANGED
@@ -5,8 +5,9 @@ import logging
|
|
5
5
|
import sys
|
6
6
|
import typing as ta
|
7
7
|
|
8
|
-
from
|
9
|
-
from ..
|
8
|
+
from ...lite.check import check
|
9
|
+
from ..contexts import LoggingContext
|
10
|
+
from ..contexts import LoggingExcInfoTuple
|
10
11
|
from ..warnings import LoggingSetupWarning
|
11
12
|
|
12
13
|
|
@@ -268,19 +269,33 @@ class LoggingContextLogRecord(logging.LogRecord):
|
|
268
269
|
self.msecs: float = times.msecs
|
269
270
|
self.relativeCreated: float = times.relative_created
|
270
271
|
|
271
|
-
|
272
|
-
|
273
|
-
|
272
|
+
if logging.logThreads:
|
273
|
+
thread = check.not_none(ctx.thread())
|
274
|
+
self.thread: ta.Optional[int] = thread.ident
|
275
|
+
self.threadName: ta.Optional[str] = thread.name
|
276
|
+
else:
|
277
|
+
self.thread = None
|
278
|
+
self.threadName = None
|
274
279
|
|
275
|
-
|
276
|
-
|
280
|
+
if logging.logProcesses:
|
281
|
+
process = check.not_none(ctx.process())
|
282
|
+
self.process: ta.Optional[int] = process.pid
|
283
|
+
else:
|
284
|
+
self.process = None
|
277
285
|
|
278
|
-
if
|
279
|
-
|
286
|
+
if logging.logMultiprocessing:
|
287
|
+
if (mp := ctx.multiprocessing()) is not None:
|
288
|
+
self.processName: ta.Optional[str] = mp.process_name
|
289
|
+
else:
|
290
|
+
self.processName = None
|
280
291
|
else:
|
281
292
|
self.processName = None
|
282
293
|
|
283
|
-
|
284
|
-
|
294
|
+
# Absent <3.12
|
295
|
+
if getattr(logging, 'logAsyncioTasks', None):
|
296
|
+
if (at := ctx.asyncio_task()) is not None:
|
297
|
+
self.taskName: ta.Optional[str] = at.name
|
298
|
+
else:
|
299
|
+
self.taskName = None
|
285
300
|
else:
|
286
301
|
self.taskName = None
|
omlish/logs/times.py
CHANGED
@@ -4,13 +4,14 @@ import logging
|
|
4
4
|
import time
|
5
5
|
import typing as ta
|
6
6
|
|
7
|
+
from .infos import LoggingContextInfo
|
7
8
|
from .warnings import LoggingSetupWarning
|
8
9
|
|
9
10
|
|
10
11
|
##
|
11
12
|
|
12
13
|
|
13
|
-
class LoggingTimeFields(ta.NamedTuple):
|
14
|
+
class LoggingTimeFields(LoggingContextInfo, ta.NamedTuple): # type: ignore[misc]
|
14
15
|
"""Maps directly to stdlib `logging.LogRecord` fields, and must be kept in sync with it."""
|
15
16
|
|
16
17
|
created: float
|
omlish/manifests/loading.py
CHANGED
@@ -8,6 +8,12 @@ TODO:
|
|
8
8
|
- TypeMap style weak cache of issubclass queries
|
9
9
|
- wait.. lazily load the class for virtual subclass queries? xor support virtual bases?
|
10
10
|
- weakref class dict keys?
|
11
|
+
- cheap_discover_package_root_dirs: Seq[str] | None = None or smth
|
12
|
+
- maaaybe.. add an EnvVar? OMLISH_MANIFEST_ROOT_DIRS? if set to : delimited, turns off package disco and overrides
|
13
|
+
scan_root_dirs
|
14
|
+
- currently the cli cant subprocess itself and keep manifests working
|
15
|
+
- EnvVar cls is already lite
|
16
|
+
|
11
17
|
"""
|
12
18
|
import dataclasses as dc
|
13
19
|
import importlib.machinery
|
omlish/sockets/server/server.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.omlish-manifests.json,sha256=FLw7xkPiSXuImZgqSP8BwrEib2R1doSzUPLUkc-QUIA,8410
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=QkXaBAuv7ZX9gYuayTSwd9nc5AxEetkjHMvq5rsSLtM,3575
|
3
3
|
omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
|
4
4
|
omlish/c3.py,sha256=ZNIMl1kwg3qdei4DiUrJPQe5M81S1e76N-GuNSwLBAE,8683
|
5
5
|
omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
|
@@ -498,25 +498,26 @@ omlish/lite/typing.py,sha256=m2CyJTz2OVOCPRvp-0UuEx7oleZgXqs3rYXijE0bTsA,1280
|
|
498
498
|
omlish/lite/wrappers.py,sha256=d00Ls2kFHuogKd5wEBaU65VNCN10YXIZtiwu1mbMpmA,530
|
499
499
|
omlish/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
500
500
|
omlish/logs/all.py,sha256=9VOobL0p3E_6QWsnBmlCPhxz5zqs-AiH4jvZR3--ZZA,1085
|
501
|
-
omlish/logs/base.py,sha256=
|
502
|
-
omlish/logs/callers.py,sha256=
|
503
|
-
omlish/logs/
|
501
|
+
omlish/logs/base.py,sha256=LxDnvCDzZr9AfjO_5NmoE9z1Mqw_7meQ7WGgGYissXk,6649
|
502
|
+
omlish/logs/callers.py,sha256=tRj24LxlEimDGCplDVVJDvRSt_u72cgjnnvb0mdZgvU,2065
|
503
|
+
omlish/logs/contexts.py,sha256=apXaLOk7LlXNdz_gpF5zHhTLpFFBmB2_SHX8UVxopks,6537
|
504
|
+
omlish/logs/infos.py,sha256=VPx9VrcN1fCPnXjc8QCsMlww0fgEG3qdkzo2KhSxMwY,2716
|
504
505
|
omlish/logs/levels.py,sha256=b3i-70OcvNMcOQBzg1IUHBPESfHz0uu5mi5t_jbwv1Y,1966
|
505
506
|
omlish/logs/modules.py,sha256=EFOqubbU5P0GW576OL6j9fmizNN2oyfpsp5YnKCoUgk,194
|
506
|
-
omlish/logs/protocols.py,sha256=
|
507
|
+
omlish/logs/protocols.py,sha256=8l5TgNUNgfrqYPA6dVijPFGLxzWhvgS4Cca64XHT0jo,939
|
507
508
|
omlish/logs/standard.py,sha256=ppho-wDecGxUiRXOdCIlblmrQhqXZ0oQOGayy8N53XY,3237
|
508
|
-
omlish/logs/times.py,sha256=
|
509
|
+
omlish/logs/times.py,sha256=ro2TSD_Xwq_cNN8f_FrEGfdhD4PTbh0PLSG13PGx39E,2571
|
509
510
|
omlish/logs/utils.py,sha256=fKvP342qBmE8wwTgUQ8Tf0-ATVhCm90UYBQt2pk0044,1883
|
510
511
|
omlish/logs/warnings.py,sha256=xyhDgiPy1p8Kp5D9sb_NZiBnQ26SUppaHqC27dtQzok,67
|
511
512
|
omlish/logs/std/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
512
|
-
omlish/logs/std/adapters.py,sha256=
|
513
|
+
omlish/logs/std/adapters.py,sha256=qRXusW8iGYF29C3cy1srb4pgJ0Fv5li8bUvnegxo9o8,1005
|
513
514
|
omlish/logs/std/configs.py,sha256=aDQahqBJXJpmQBaxXVK5S2xi_I_nrLLcCLTq6Q2K6EQ,1037
|
514
515
|
omlish/logs/std/filters.py,sha256=Z8tHOvBRiP-OYm2z5cwY-lYXRimNgferEARMwvwx5Pw,380
|
515
516
|
omlish/logs/std/handlers.py,sha256=nYPKV6Kzz8Oeyw4-3ZdJKKEUfgubfmwzqr3RaCNcmS4,338
|
516
517
|
omlish/logs/std/json.py,sha256=QJ5lywLsRsPyVno2nk2kOw-Z1z3bfrDiZzqcRUdWUMY,1382
|
517
518
|
omlish/logs/std/noisy.py,sha256=hWpbseerZqlHdEPEajDTSmcRhx8LmmNAxz_7GBZAO9s,353
|
518
519
|
omlish/logs/std/proxy.py,sha256=9MVV5kbj9nwl3KZGtrYCIb5XTpv33f33zZ7P_B58fX0,2394
|
519
|
-
omlish/logs/std/records.py,sha256=
|
520
|
+
omlish/logs/std/records.py,sha256=muJA3KKjGm5mgsHXtOyrpaEZu553M-UviNgNvXdISXY,10718
|
520
521
|
omlish/logs/typed/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
521
522
|
omlish/logs/typed/bindings.py,sha256=H_B-3LTGFlBIWYDJ8rei1VMfInE8KrBwRo3bJ_BgFj8,18184
|
522
523
|
omlish/logs/typed/contexts.py,sha256=MU1RqHtmYbnxoLfLhMZbTbRd-WfYEyeVo7_3VnG3rY0,4027
|
@@ -525,7 +526,7 @@ omlish/logs/typed/values.py,sha256=w8ukpJZ3lx_st7Mj7riP2squzGmMaz7OuUxw_NZCZsY,3
|
|
525
526
|
omlish/manifests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
526
527
|
omlish/manifests/base.py,sha256=wW-De-pU3cef-0vGsgo-ypftDwc3tCBxhRAzPtrdark,918
|
527
528
|
omlish/manifests/globals.py,sha256=kVqQ-fT4kc7xWzLHoI731GviitFPv2v2yqw-p7t7Exs,2628
|
528
|
-
omlish/manifests/loading.py,sha256=
|
529
|
+
omlish/manifests/loading.py,sha256=s6KnhdFQCsI2i0Rus1sMU0so2v8dUBnk59BJkSnxGt8,17514
|
529
530
|
omlish/manifests/static.py,sha256=9BaPBLkuzxHmg5A-5k9BjjBFINCdmFOIu06dMFgCfz4,497
|
530
531
|
omlish/manifests/types.py,sha256=NeOGuIVrcbqjCDbQ3MnCxxHAgHnw0CkWJsBzo230PWE,453
|
531
532
|
omlish/marshal/__init__.py,sha256=cdRll_tPZaTBIY0yLejCXZdZB3fUVkIoDMb8aESLkl8,5981
|
@@ -646,7 +647,7 @@ omlish/sockets/ports.py,sha256=WofuoMTQNUhbEreL0lrMQyVEZm6awuLLpFvn6jnFKrw,1778
|
|
646
647
|
omlish/sockets/wait.py,sha256=GQIRABh_NWHePuNVz5bBeg7iVln-YHc3945ZA0qr-mA,1565
|
647
648
|
omlish/sockets/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
648
649
|
omlish/sockets/server/handlers.py,sha256=T--CSns9810f25--0Blv5bspAXhMjULtKEcXSGUpxOo,3912
|
649
|
-
omlish/sockets/server/server.py,sha256=
|
650
|
+
omlish/sockets/server/server.py,sha256=Il1y0LHRa_eB6FLLcuVXbfu9tLOpOttLBCffh3wWSBA,6289
|
650
651
|
omlish/sockets/server/ssl.py,sha256=QLiPcng1f1RFDhw4aS-Fy57fm0R7CXm76STpHmT55z0,1067
|
651
652
|
omlish/sockets/server/threading.py,sha256=CPr_290vpN3o4p2ehQBIwk-d8Ciasylp9v2zUQSB5xk,2862
|
652
653
|
omlish/specs/__init__.py,sha256=fxpcfXEWESH2kiPStKhl2dAdfLkZVTt_cssZKyqBLiQ,87
|
@@ -891,9 +892,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
|
|
891
892
|
omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
|
892
893
|
omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
|
893
894
|
omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
|
894
|
-
omlish-0.0.0.
|
895
|
-
omlish-0.0.0.
|
896
|
-
omlish-0.0.0.
|
897
|
-
omlish-0.0.0.
|
898
|
-
omlish-0.0.0.
|
899
|
-
omlish-0.0.0.
|
895
|
+
omlish-0.0.0.dev427.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
896
|
+
omlish-0.0.0.dev427.dist-info/METADATA,sha256=XcyPFrnqymcaHcY3ycLj3wJn1_l-E-qdd3MilxfuI8o,19243
|
897
|
+
omlish-0.0.0.dev427.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
898
|
+
omlish-0.0.0.dev427.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
899
|
+
omlish-0.0.0.dev427.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
900
|
+
omlish-0.0.0.dev427.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|