omlish 0.0.0.dev423__py3-none-any.whl → 0.0.0.dev425__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 +3 -3
- omlish/dataclasses/impl/configs.py +2 -1
- omlish/formats/json/stream/lexing.py +8 -0
- omlish/formats/json/stream/utils.py +3 -0
- omlish/formats/json5/streams.py +22 -0
- omlish/lang/__init__.py +3 -1
- omlish/lang/asyncs.py +12 -0
- omlish/lang/functions.py +0 -11
- omlish/lang/lazyglobals.py +27 -5
- omlish/lang/maysync.py +2 -2
- omlish/lifecycles/contextmanagers.py +1 -2
- omlish/lifecycles/controller.py +1 -2
- omlish/lite/asyncs.py +15 -0
- omlish/lite/timing.py +2 -2
- omlish/logs/all.py +23 -34
- omlish/logs/base.py +248 -0
- omlish/logs/callers.py +21 -15
- omlish/logs/infos.py +105 -0
- omlish/logs/levels.py +64 -0
- omlish/logs/protocols.py +31 -0
- omlish/logs/standard.py +12 -11
- omlish/logs/std/adapters.py +41 -0
- omlish/logs/std/configs.py +29 -0
- omlish/logs/{filters.py → std/filters.py} +1 -1
- omlish/logs/{handlers.py → std/handlers.py} +1 -1
- omlish/logs/{json.py → std/json.py} +2 -2
- omlish/logs/{proxy.py → std/proxy.py} +3 -3
- omlish/logs/std/records.py +286 -0
- omlish/logs/times.py +89 -0
- omlish/logs/typed/bindings.py +24 -0
- omlish/logs/utils.py +60 -4
- omlish/logs/warnings.py +8 -0
- omlish/manifests/loading.py +1 -1
- omlish/os/journald.py +3 -3
- omlish/testing/pytest/plugins/skips.py +0 -4
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev425.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev425.dist-info}/RECORD +44 -86
- omlish/defs.py +0 -216
- omlish/dispatch/_dispatch2.py +0 -69
- omlish/dispatch/_dispatch3.py +0 -108
- omlish/dynamic.py +0 -219
- omlish/formats/json/Json.g4 +0 -77
- omlish/formats/json/_antlr/JsonLexer.py +0 -109
- omlish/formats/json/_antlr/JsonListener.py +0 -61
- omlish/formats/json/_antlr/JsonParser.py +0 -457
- omlish/formats/json/_antlr/JsonVisitor.py +0 -42
- omlish/io/trampoline.py +0 -289
- omlish/logs/abc.py +0 -319
- omlish/logs/color.py +0 -27
- omlish/logs/configs.py +0 -29
- omlish/logs/protocol.py +0 -218
- omlish/logs/timing.py +0 -58
- omlish/specs/irc/__init__.py +0 -0
- omlish/specs/irc/messages/__init__.py +0 -0
- omlish/specs/irc/messages/base.py +0 -49
- omlish/specs/irc/messages/formats.py +0 -92
- omlish/specs/irc/messages/messages.py +0 -774
- omlish/specs/irc/messages/parsing.py +0 -98
- omlish/specs/irc/numerics/__init__.py +0 -0
- omlish/specs/irc/numerics/formats.py +0 -97
- omlish/specs/irc/numerics/numerics.py +0 -865
- omlish/specs/irc/numerics/types.py +0 -59
- omlish/specs/irc/protocol/LICENSE +0 -11
- omlish/specs/irc/protocol/__init__.py +0 -61
- omlish/specs/irc/protocol/consts.py +0 -6
- omlish/specs/irc/protocol/errors.py +0 -30
- omlish/specs/irc/protocol/message.py +0 -21
- omlish/specs/irc/protocol/nuh.py +0 -55
- omlish/specs/irc/protocol/parsing.py +0 -158
- omlish/specs/irc/protocol/rendering.py +0 -153
- omlish/specs/irc/protocol/tags.py +0 -102
- omlish/specs/irc/protocol/utils.py +0 -30
- omlish/specs/proto/Protobuf3.g4 +0 -396
- omlish/specs/proto/__init__.py +0 -0
- omlish/specs/proto/_antlr/Protobuf3Lexer.py +0 -340
- omlish/specs/proto/_antlr/Protobuf3Listener.py +0 -448
- omlish/specs/proto/_antlr/Protobuf3Parser.py +0 -3909
- omlish/specs/proto/_antlr/Protobuf3Visitor.py +0 -257
- omlish/specs/proto/_antlr/__init__.py +0 -0
- omlish/specs/proto/nodes.py +0 -54
- omlish/specs/proto/parsing.py +0 -97
- omlish/sql/parsing/Minisql.g4 +0 -292
- omlish/sql/parsing/__init__.py +0 -0
- omlish/sql/parsing/_antlr/MinisqlLexer.py +0 -322
- omlish/sql/parsing/_antlr/MinisqlListener.py +0 -511
- omlish/sql/parsing/_antlr/MinisqlParser.py +0 -3763
- omlish/sql/parsing/_antlr/MinisqlVisitor.py +0 -292
- omlish/sql/parsing/_antlr/__init__.py +0 -0
- omlish/sql/parsing/parsing.py +0 -119
- /omlish/{.manifests.json → .omlish-manifests.json} +0 -0
- /omlish/{formats/json/_antlr → logs/std}/__init__.py +0 -0
- /omlish/logs/{noisy.py → std/noisy.py} +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev425.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev425.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev425.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev425.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
__version__ = '0.0.0.
|
2
|
-
__revision__ = '
|
1
|
+
__version__ = '0.0.0.dev425'
|
2
|
+
__revision__ = '92376f181ba36a2d1eda16643d70fd1077e309f1'
|
3
3
|
|
4
4
|
|
5
5
|
#
|
@@ -175,7 +175,7 @@ class SetuptoolsBase:
|
|
175
175
|
'*.g4',
|
176
176
|
'*.h',
|
177
177
|
|
178
|
-
'.manifests.json',
|
178
|
+
'.omlish-manifests.json',
|
179
179
|
|
180
180
|
'LICENSE',
|
181
181
|
'LICENSE.txt',
|
@@ -117,9 +117,11 @@ class JsonStreamLexer(GenMachine[str, Token]):
|
|
117
117
|
*,
|
118
118
|
include_raw: bool = False,
|
119
119
|
include_space: bool = False,
|
120
|
+
allow_comments: bool = False,
|
120
121
|
) -> None:
|
121
122
|
self._include_raw = include_raw
|
122
123
|
self._include_space = include_space
|
124
|
+
self._allow_comments = allow_comments
|
123
125
|
|
124
126
|
self._ofs = 0
|
125
127
|
self._line = 1
|
@@ -200,6 +202,9 @@ class JsonStreamLexer(GenMachine[str, Token]):
|
|
200
202
|
if c in 'tfnIN':
|
201
203
|
return self._do_const(c)
|
202
204
|
|
205
|
+
if self._allow_comments and c == '/':
|
206
|
+
return self._do_comment()
|
207
|
+
|
203
208
|
self._raise(f'Unexpected character: {c}')
|
204
209
|
|
205
210
|
def _do_string(self):
|
@@ -321,3 +326,6 @@ class JsonStreamLexer(GenMachine[str, Token]):
|
|
321
326
|
yield self._make_tok(tk, tv, raw, pos)
|
322
327
|
|
323
328
|
return self._do_main()
|
329
|
+
|
330
|
+
def _do_comment(self):
|
331
|
+
raise NotImplementedError
|
@@ -15,6 +15,8 @@ class JsonStreamValueParser(lang.ExitStacked):
|
|
15
15
|
include_raw: bool = False
|
16
16
|
yield_object_lists: bool = False
|
17
17
|
|
18
|
+
json5: bool = False
|
19
|
+
|
18
20
|
#
|
19
21
|
|
20
22
|
_lex: JsonStreamLexer = dc.field(init=False)
|
@@ -24,6 +26,7 @@ class JsonStreamValueParser(lang.ExitStacked):
|
|
24
26
|
def _enter_contexts(self) -> None:
|
25
27
|
self._lex = JsonStreamLexer(
|
26
28
|
include_raw=self.include_raw,
|
29
|
+
allow_comments=self.json5,
|
27
30
|
)
|
28
31
|
|
29
32
|
self._parse = JsonStreamParser()
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
|
4
|
+
Objects:
|
5
|
+
- Object keys may be an ECMAScript 5.1 IdentifierName.
|
6
|
+
- Objects may have a single trailing comma.
|
7
|
+
Arrays:
|
8
|
+
- Arrays may have a single trailing comma.
|
9
|
+
Strings:
|
10
|
+
- Strings may be single quoted.
|
11
|
+
- Strings may span multiple lines by escaping new line characters.
|
12
|
+
- Strings may include character escapes.
|
13
|
+
Numbers:
|
14
|
+
- Numbers may be hexadecimal.
|
15
|
+
- Numbers may have a leading or trailing decimal point.
|
16
|
+
- Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
|
17
|
+
- Numbers may begin with an explicit plus sign.
|
18
|
+
Comments:
|
19
|
+
- Single and multi-line comments are allowed.
|
20
|
+
White Space:
|
21
|
+
- Additional white space characters are allowed.
|
22
|
+
"""
|
omlish/lang/__init__.py
CHANGED
@@ -9,6 +9,8 @@ with _auto_proxy_init(
|
|
9
9
|
##
|
10
10
|
|
11
11
|
from .asyncs import ( # noqa
|
12
|
+
as_async,
|
13
|
+
|
12
14
|
async_list,
|
13
15
|
|
14
16
|
sync_await,
|
@@ -216,7 +218,6 @@ with _auto_proxy_init(
|
|
216
218
|
|
217
219
|
from .functions import ( # noqa
|
218
220
|
VoidError,
|
219
|
-
as_async,
|
220
221
|
call_with,
|
221
222
|
coalesce,
|
222
223
|
cond_kw,
|
@@ -306,6 +307,7 @@ with _auto_proxy_init(
|
|
306
307
|
)
|
307
308
|
|
308
309
|
from .lazyglobals import ( # noqa
|
310
|
+
AmbiguousLazyGlobalsFallbackError,
|
309
311
|
LazyGlobals,
|
310
312
|
)
|
311
313
|
|
omlish/lang/asyncs.py
CHANGED
@@ -1,7 +1,19 @@
|
|
1
|
+
import functools
|
1
2
|
import typing as ta
|
2
3
|
|
3
4
|
|
4
5
|
T = ta.TypeVar('T')
|
6
|
+
P = ta.ParamSpec('P')
|
7
|
+
|
8
|
+
|
9
|
+
##
|
10
|
+
|
11
|
+
|
12
|
+
def as_async(fn: ta.Callable[P, T], *, wrap: bool = False) -> ta.Callable[P, ta.Awaitable[T]]:
|
13
|
+
async def inner(*args, **kwargs):
|
14
|
+
return fn(*args, **kwargs)
|
15
|
+
|
16
|
+
return functools.wraps(fn)(inner) if wrap else inner
|
5
17
|
|
6
18
|
|
7
19
|
##
|
omlish/lang/functions.py
CHANGED
@@ -167,17 +167,6 @@ def void(*args: ta.Any, **kwargs: ta.Any) -> ta.NoReturn:
|
|
167
167
|
##
|
168
168
|
|
169
169
|
|
170
|
-
def as_async(fn: ta.Callable[P, T]) -> ta.Callable[P, ta.Awaitable[T]]:
|
171
|
-
@functools.wraps(fn)
|
172
|
-
async def inner(*args, **kwargs):
|
173
|
-
return fn(*args, **kwargs)
|
174
|
-
|
175
|
-
return inner
|
176
|
-
|
177
|
-
|
178
|
-
##
|
179
|
-
|
180
|
-
|
181
170
|
_MISSING = object()
|
182
171
|
|
183
172
|
|
omlish/lang/lazyglobals.py
CHANGED
@@ -4,6 +4,17 @@ import typing as ta
|
|
4
4
|
##
|
5
5
|
|
6
6
|
|
7
|
+
class AmbiguousLazyGlobalsFallbackError(Exception):
|
8
|
+
def __init__(self, attr: str, fallbacks: list[ta.Callable[[str], ta.Any]]) -> None:
|
9
|
+
super().__init__()
|
10
|
+
|
11
|
+
self.attr = attr
|
12
|
+
self.fallbacks = fallbacks
|
13
|
+
|
14
|
+
def __repr__(self) -> str:
|
15
|
+
return f'{self.__class__.__name__}({self.attr!r}, {self.fallbacks!r})'
|
16
|
+
|
17
|
+
|
7
18
|
class LazyGlobals:
|
8
19
|
def __init__(
|
9
20
|
self,
|
@@ -17,6 +28,7 @@ class LazyGlobals:
|
|
17
28
|
self._update_globals = update_globals
|
18
29
|
|
19
30
|
self._attr_fns: dict[str, ta.Callable[[], ta.Any]] = {}
|
31
|
+
self._fallback_fns: list[ta.Callable[[str], ta.Callable[[], ta.Any]]] = []
|
20
32
|
|
21
33
|
@classmethod
|
22
34
|
def install(cls, globals: ta.MutableMapping[str, ta.Any]) -> 'LazyGlobals': # noqa
|
@@ -42,13 +54,23 @@ class LazyGlobals:
|
|
42
54
|
self._attr_fns[attr] = fn
|
43
55
|
return self
|
44
56
|
|
57
|
+
def add_fallback_fn(self, fn: ta.Callable[[str], ta.Callable[[], ta.Any]]) -> 'LazyGlobals':
|
58
|
+
self._fallback_fns.append(fn)
|
59
|
+
return self
|
60
|
+
|
45
61
|
def get(self, attr: str) -> ta.Any:
|
46
|
-
|
47
|
-
fn = self._attr_fns[attr]
|
48
|
-
except KeyError:
|
49
|
-
raise AttributeError(attr) from None
|
62
|
+
val: ta.Any
|
50
63
|
|
51
|
-
|
64
|
+
if (attr_fn := self._attr_fns.get(attr)) is not None:
|
65
|
+
val = attr_fn()
|
66
|
+
|
67
|
+
elif (fallbacks := [(fb_fn, fb_fn(attr)) for fb_fn in self._fallback_fns]):
|
68
|
+
if len(fallbacks) > 1:
|
69
|
+
raise AmbiguousLazyGlobalsFallbackError(attr, [fb_fn for fb_fn, _ in fallbacks])
|
70
|
+
[val] = fallbacks
|
71
|
+
|
72
|
+
else:
|
73
|
+
raise AttributeError(attr)
|
52
74
|
|
53
75
|
if self._update_globals and self._globals is not None:
|
54
76
|
self._globals[attr] = val
|
omlish/lang/maysync.py
CHANGED
@@ -3,7 +3,7 @@ import typing as ta
|
|
3
3
|
from ..lite.maysync import MaysyncFn
|
4
4
|
from ..lite.maysync import MaysyncGeneratorFn
|
5
5
|
from ..lite.maysync import make_maysync as _make_maysync
|
6
|
-
from .
|
6
|
+
from .asyncs import as_async
|
7
7
|
|
8
8
|
|
9
9
|
T = ta.TypeVar('T')
|
@@ -68,5 +68,5 @@ def make_maysync_from_sync(
|
|
68
68
|
) -> ta.Callable[P, ta.Awaitable[T]]:
|
69
69
|
return _make_maysync(
|
70
70
|
s,
|
71
|
-
a if a is not None else as_async(s),
|
71
|
+
a if a is not None else as_async(s, wrap=True),
|
72
72
|
)
|
@@ -2,7 +2,6 @@ import types
|
|
2
2
|
import typing as ta
|
3
3
|
|
4
4
|
from .. import dataclasses as dc
|
5
|
-
from .. import defs
|
6
5
|
from .. import lang
|
7
6
|
from .base import Lifecycle
|
8
7
|
from .controller import LifecycleController
|
@@ -37,7 +36,7 @@ class LifecycleContextManager(ta.Generic[LifecycleT]):
|
|
37
36
|
self._lifecycle = lifecycle
|
38
37
|
self._controller = lifecycle if isinstance(lifecycle, LifecycleController) else LifecycleController(lifecycle)
|
39
38
|
|
40
|
-
|
39
|
+
__repr__ = lang.AttrRepr(['lifecycle', 'state'])
|
41
40
|
|
42
41
|
@property
|
43
42
|
def lifecycle(self) -> LifecycleT:
|
omlish/lifecycles/controller.py
CHANGED
@@ -2,7 +2,6 @@ import abc
|
|
2
2
|
import typing as ta
|
3
3
|
|
4
4
|
from .. import check
|
5
|
-
from .. import defs
|
6
5
|
from .. import lang
|
7
6
|
from .base import AnyLifecycle # noqa
|
8
7
|
from .base import Lifecycle # noqa
|
@@ -48,7 +47,7 @@ class AnyLifecycleController(AnyLifecycle[R], lang.Abstract, ta.Generic[AnyLifec
|
|
48
47
|
self._state = LifecycleStates.NEW
|
49
48
|
self._listeners: list[AnyLifecycleListener[AnyLifecycleT, R]] = []
|
50
49
|
|
51
|
-
|
50
|
+
__repr__ = lang.AttrRepr(['lifecycle', 'state'])
|
52
51
|
|
53
52
|
@property
|
54
53
|
def lifecycle(self) -> AnyLifecycleT:
|
omlish/lite/asyncs.py
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
import functools
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
|
5
|
+
T = ta.TypeVar('T')
|
6
|
+
|
7
|
+
|
8
|
+
##
|
9
|
+
|
10
|
+
|
11
|
+
def as_async(fn: ta.Callable[..., T], *, wrap: bool = False) -> ta.Callable[..., ta.Awaitable[T]]:
|
12
|
+
async def inner(*args, **kwargs):
|
13
|
+
return fn(*args, **kwargs)
|
14
|
+
|
15
|
+
return functools.wraps(fn)(inner) if wrap else inner
|
omlish/lite/timing.py
CHANGED
omlish/logs/all.py
CHANGED
@@ -5,64 +5,53 @@ from .. import lang as _lang
|
|
5
5
|
with _lang.auto_proxy_init(globals()):
|
6
6
|
##
|
7
7
|
|
8
|
-
from .
|
9
|
-
|
10
|
-
)
|
11
|
-
|
12
|
-
from .color import ( # noqa
|
13
|
-
ColorLogFormatter,
|
8
|
+
from .std.filters import ( # noqa
|
9
|
+
TidLoggingFilter,
|
14
10
|
)
|
15
11
|
|
16
|
-
from .
|
17
|
-
|
12
|
+
from .std.handlers import ( # noqa
|
13
|
+
ListLoggingHandler,
|
18
14
|
)
|
19
15
|
|
20
|
-
from .
|
21
|
-
|
16
|
+
from .std.json import ( # noqa
|
17
|
+
JsonLoggingFormatter,
|
22
18
|
)
|
23
19
|
|
24
|
-
from .
|
25
|
-
|
20
|
+
from .std.noisy import ( # noqa
|
21
|
+
silence_noisy_loggers,
|
26
22
|
)
|
27
23
|
|
28
|
-
from .
|
29
|
-
|
24
|
+
from .std.proxy import ( # noqa
|
25
|
+
ProxyLoggingFilterer,
|
26
|
+
ProxyLoggingHandler,
|
30
27
|
)
|
31
28
|
|
32
|
-
from .
|
33
|
-
|
29
|
+
from .callers import ( # noqa
|
30
|
+
LoggingCaller,
|
34
31
|
)
|
35
32
|
|
36
|
-
from .
|
37
|
-
|
38
|
-
Logging,
|
39
|
-
AsyncLogging,
|
40
|
-
|
41
|
-
AnyAbstractLogging,
|
42
|
-
AbstractLogging,
|
43
|
-
AbstractAsyncLogging,
|
44
|
-
|
45
|
-
AnyNopLogging,
|
46
|
-
NopLogging,
|
47
|
-
NopAsyncLogging,
|
33
|
+
from .levels import ( # noqa
|
34
|
+
LogLevel,
|
48
35
|
|
49
|
-
|
36
|
+
NamedLogLevel,
|
50
37
|
)
|
51
38
|
|
52
|
-
from .
|
53
|
-
|
54
|
-
ProxyLogHandler,
|
39
|
+
from .protocols import ( # noqa
|
40
|
+
LoggerLike,
|
55
41
|
)
|
56
42
|
|
57
43
|
from .standard import ( # noqa
|
58
44
|
STANDARD_LOG_FORMAT_PARTS,
|
59
|
-
|
45
|
+
StandardLoggingFormatter,
|
60
46
|
|
61
|
-
|
47
|
+
StandardConfiguredLoggingHandler,
|
62
48
|
|
63
49
|
configure_standard_logging,
|
64
50
|
)
|
65
51
|
|
66
52
|
from .utils import ( # noqa
|
53
|
+
LogTimingContext,
|
54
|
+
log_timing_context,
|
55
|
+
|
67
56
|
error_logging,
|
68
57
|
)
|
omlish/logs/base.py
ADDED
@@ -0,0 +1,248 @@
|
|
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 NamedLogLevel
|
17
|
+
from .times import LoggingTimeFields
|
18
|
+
|
19
|
+
|
20
|
+
T = ta.TypeVar('T')
|
21
|
+
|
22
|
+
|
23
|
+
LogLevel = int # ta.TypeAlias
|
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
|
28
|
+
|
29
|
+
|
30
|
+
##
|
31
|
+
|
32
|
+
|
33
|
+
@ta.final
|
34
|
+
class LoggingContext:
|
35
|
+
level: NamedLogLevel
|
36
|
+
|
37
|
+
time_ns: int
|
38
|
+
|
39
|
+
exc_info: ta.Optional[LoggingExcInfo] = None
|
40
|
+
exc_info_tuple: ta.Optional[LoggingExcInfoTuple] = None
|
41
|
+
|
42
|
+
@ta.final
|
43
|
+
class NOT_SET: # noqa
|
44
|
+
def __new__(cls, *args, **kwargs): # noqa
|
45
|
+
raise TypeError
|
46
|
+
|
47
|
+
#
|
48
|
+
|
49
|
+
def __init__(
|
50
|
+
self,
|
51
|
+
level: LogLevel,
|
52
|
+
*,
|
53
|
+
time_ns: ta.Optional[int] = None,
|
54
|
+
|
55
|
+
exc_info: LoggingExcInfoArg = False,
|
56
|
+
|
57
|
+
caller: ta.Union[LoggingCaller, ta.Type[NOT_SET], None] = NOT_SET,
|
58
|
+
stack_offset: int = 0,
|
59
|
+
stack_info: bool = False,
|
60
|
+
) -> None:
|
61
|
+
self.level = level if level.__class__ is NamedLogLevel else NamedLogLevel(level) # type: ignore[assignment]
|
62
|
+
|
63
|
+
#
|
64
|
+
|
65
|
+
if time_ns is None:
|
66
|
+
time_ns = time.time_ns()
|
67
|
+
self.time_ns: int = time_ns
|
68
|
+
|
69
|
+
#
|
70
|
+
|
71
|
+
if exc_info is True:
|
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
|
86
|
+
|
87
|
+
#
|
88
|
+
|
89
|
+
if caller is not LoggingContext.NOT_SET:
|
90
|
+
self._caller = caller # type: ignore[assignment]
|
91
|
+
else:
|
92
|
+
self._stack_offset = stack_offset
|
93
|
+
self._stack_info = stack_info
|
94
|
+
|
95
|
+
#
|
96
|
+
|
97
|
+
self.thread = LoggingThreadInfo.build()
|
98
|
+
self.process = LoggingProcessInfo.build()
|
99
|
+
self.multiprocessing = LoggingMultiprocessingInfo.build()
|
100
|
+
self.asyncio_task = LoggingAsyncioTaskInfo.build()
|
101
|
+
|
102
|
+
#
|
103
|
+
|
104
|
+
_times: LoggingTimeFields
|
105
|
+
|
106
|
+
@property
|
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
|
+
#
|
117
|
+
|
118
|
+
def inc_stack_offset(self, ofs: int = 1) -> 'LoggingContext':
|
119
|
+
if hasattr(self, '_stack_offset'):
|
120
|
+
self._stack_offset += ofs
|
121
|
+
return self
|
122
|
+
|
123
|
+
_caller: ta.Optional[LoggingCaller]
|
124
|
+
|
125
|
+
def build_caller(self) -> ta.Optional[LoggingCaller]:
|
126
|
+
"""Must be cooperatively called only from the exact configured _stack_offset."""
|
127
|
+
|
128
|
+
try:
|
129
|
+
return self._caller
|
130
|
+
except AttributeError:
|
131
|
+
pass
|
132
|
+
|
133
|
+
caller = self._caller = LoggingCaller.find(
|
134
|
+
self._stack_offset + 1,
|
135
|
+
stack_info=self._stack_info,
|
136
|
+
)
|
137
|
+
return caller
|
138
|
+
|
139
|
+
def caller(self) -> ta.Optional[LoggingCaller]:
|
140
|
+
try:
|
141
|
+
return self._caller
|
142
|
+
except AttributeError:
|
143
|
+
return None
|
144
|
+
|
145
|
+
_source_file: ta.Optional[LoggingSourceFileInfo]
|
146
|
+
|
147
|
+
def source_file(self) -> ta.Optional[LoggingSourceFileInfo]:
|
148
|
+
try:
|
149
|
+
return self._source_file
|
150
|
+
except AttributeError:
|
151
|
+
pass
|
152
|
+
|
153
|
+
if (caller := self.caller()) is None:
|
154
|
+
return None
|
155
|
+
|
156
|
+
src_file = self._source_file = LoggingSourceFileInfo.build(caller.file_path)
|
157
|
+
return src_file
|
158
|
+
|
159
|
+
|
160
|
+
##
|
161
|
+
|
162
|
+
|
163
|
+
class AnyLogger(Abstract, ta.Generic[T]):
|
164
|
+
def is_enabled_for(self, level: LogLevel) -> bool:
|
165
|
+
return self.get_effective_level() >= level
|
166
|
+
|
167
|
+
@abc.abstractmethod
|
168
|
+
def get_effective_level(self) -> LogLevel:
|
169
|
+
raise NotImplementedError
|
170
|
+
|
171
|
+
#
|
172
|
+
|
173
|
+
@ta.final
|
174
|
+
def isEnabledFor(self, level: LogLevel) -> bool: # noqa
|
175
|
+
return self.is_enabled_for(level)
|
176
|
+
|
177
|
+
@ta.final
|
178
|
+
def getEffectiveLevel(self) -> LogLevel: # noqa
|
179
|
+
return self.get_effective_level()
|
180
|
+
|
181
|
+
#
|
182
|
+
|
183
|
+
@ta.final
|
184
|
+
def debug(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
185
|
+
return self._log(LoggingContext(NamedLogLevel.DEBUG, stack_offset=1), msg, *args, **kwargs)
|
186
|
+
|
187
|
+
@ta.final
|
188
|
+
def info(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
189
|
+
return self._log(LoggingContext(NamedLogLevel.INFO, stack_offset=1), msg, *args, **kwargs)
|
190
|
+
|
191
|
+
@ta.final
|
192
|
+
def warning(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
193
|
+
return self._log(LoggingContext(NamedLogLevel.WARNING, stack_offset=1), msg, *args, **kwargs)
|
194
|
+
|
195
|
+
@ta.final
|
196
|
+
def error(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
197
|
+
return self._log(LoggingContext(NamedLogLevel.ERROR, stack_offset=1), msg, *args, **kwargs)
|
198
|
+
|
199
|
+
@ta.final
|
200
|
+
def exception(self, msg: str, *args: ta.Any, exc_info: LoggingExcInfoArg = True, **kwargs: ta.Any) -> T:
|
201
|
+
return self._log(LoggingContext(NamedLogLevel.ERROR, exc_info=exc_info, stack_offset=1), msg, *args, **kwargs)
|
202
|
+
|
203
|
+
@ta.final
|
204
|
+
def critical(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
205
|
+
return self._log(LoggingContext(NamedLogLevel.CRITICAL, stack_offset=1), msg, *args, **kwargs)
|
206
|
+
|
207
|
+
@ta.final
|
208
|
+
def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
209
|
+
return self._log(LoggingContext(level, stack_offset=1), msg, *args, **kwargs)
|
210
|
+
|
211
|
+
#
|
212
|
+
|
213
|
+
@abc.abstractmethod
|
214
|
+
def _log(self, ctx: LoggingContext, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
215
|
+
raise NotImplementedError
|
216
|
+
|
217
|
+
|
218
|
+
class Logger(AnyLogger[None], Abstract):
|
219
|
+
@abc.abstractmethod
|
220
|
+
def _log(self, ctx: LoggingContext, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
|
221
|
+
raise NotImplementedError
|
222
|
+
|
223
|
+
|
224
|
+
class AsyncLogger(AnyLogger[ta.Awaitable[None]], Abstract):
|
225
|
+
@abc.abstractmethod
|
226
|
+
def _log(self, ctx: LoggingContext, msg: str, *args: ta.Any, **kwargs: ta.Any) -> ta.Awaitable[None]:
|
227
|
+
raise NotImplementedError
|
228
|
+
|
229
|
+
|
230
|
+
##
|
231
|
+
|
232
|
+
|
233
|
+
class AnyNopLogger(AnyLogger[T], Abstract):
|
234
|
+
@ta.final
|
235
|
+
def get_effective_level(self) -> LogLevel:
|
236
|
+
return 999
|
237
|
+
|
238
|
+
|
239
|
+
@ta.final
|
240
|
+
class NopLogger(AnyNopLogger[None], Logger):
|
241
|
+
def _log(self, ctx: LoggingContext, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
|
242
|
+
pass
|
243
|
+
|
244
|
+
|
245
|
+
@ta.final
|
246
|
+
class AsyncNopLogger(AnyNopLogger[ta.Awaitable[None]], AsyncLogger):
|
247
|
+
async def _log(self, ctx: LoggingContext, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
|
248
|
+
pass
|