logger-36 2025.18__py3-none-any.whl → 2025.20__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.
- logger_36/api/content.py +0 -1
- logger_36/catalog/config/console_rich.py +1 -1
- logger_36/catalog/handler/console.py +6 -7
- logger_36/catalog/handler/console_rich.py +12 -22
- logger_36/catalog/handler/file.py +2 -6
- logger_36/catalog/handler/generic.py +29 -43
- logger_36/{task/format → constant}/rule.py +4 -25
- logger_36/task/format/message.py +1 -60
- logger_36/type/handler.py +95 -43
- logger_36/type/logger.py +93 -80
- logger_36/version.py +1 -1
- {logger_36-2025.18.dist-info → logger_36-2025.20.dist-info}/METADATA +1 -1
- {logger_36-2025.18.dist-info → logger_36-2025.20.dist-info}/RECORD +15 -16
- logger_36/type/message.py +0 -76
- {logger_36-2025.18.dist-info → logger_36-2025.20.dist-info}/WHEEL +0 -0
- {logger_36-2025.18.dist-info → logger_36-2025.20.dist-info}/top_level.txt +0 -0
logger_36/api/content.py
CHANGED
@@ -24,7 +24,7 @@ LEVEL_COLOR: dict[int, str | style_t] = {
|
|
24
24
|
}
|
25
25
|
ACTUAL_COLOR = LEVEL_COLOR[l.CRITICAL]
|
26
26
|
EXPECTED_COLOR = "green3"
|
27
|
-
|
27
|
+
RULE_COLOR = "sky_blue3"
|
28
28
|
|
29
29
|
ALTERNATIVE_BACKGROUND_FOR_LIGHT = style_t(bgcolor=color_t.from_rgb(230, 230, 230))
|
30
30
|
ALTERNATIVE_BACKGROUND_FOR_DARK = style_t(bgcolor=color_t.from_rgb(25, 25, 25))
|
@@ -8,7 +8,6 @@ import logging as l
|
|
8
8
|
import sys as s
|
9
9
|
import typing as h
|
10
10
|
|
11
|
-
from logger_36.task.format.rule import RuleAsText
|
12
11
|
from logger_36.type.handler import handler_t as base_t
|
13
12
|
|
14
13
|
|
@@ -21,18 +20,18 @@ class console_handler_t(base_t):
|
|
21
20
|
name: str | None = None,
|
22
21
|
message_width: int = -1,
|
23
22
|
level: int = l.NOTSET,
|
24
|
-
formatter: l.Formatter | None = None,
|
25
23
|
**_,
|
26
24
|
) -> h.Self:
|
27
25
|
""""""
|
28
|
-
return cls(name, message_width,
|
26
|
+
return cls(name, message_width, None, level)
|
29
27
|
|
30
28
|
def emit(self, record: l.LogRecord, /) -> None:
|
31
29
|
""""""
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
s.__stdout__.write(self.MessageFromRecord(record)[0] + "\n")
|
31
|
+
|
32
|
+
def EmitAsIs(self, message: str, /) -> None:
|
33
|
+
""""""
|
34
|
+
s.__stdout__.write(message + "\n")
|
36
35
|
|
37
36
|
|
38
37
|
"""
|
@@ -10,6 +10,7 @@ import typing as h
|
|
10
10
|
from rich.console import Console as console_t # noqa
|
11
11
|
from rich.console import RenderableType as renderable_t # noqa
|
12
12
|
from rich.markup import escape as EscapedVersion # noqa
|
13
|
+
from rich.rule import Rule as rule_t # noqa
|
13
14
|
from rich.text import Text as text_t # noqa
|
14
15
|
from rich.traceback import install as InstallTracebackHandler # noqa
|
15
16
|
|
@@ -17,15 +18,14 @@ from logger_36.catalog.config.console_rich import (
|
|
17
18
|
ACTUAL_COLOR,
|
18
19
|
ALTERNATIVE_BACKGROUND_FOR_DARK,
|
19
20
|
ALTERNATIVE_BACKGROUND_FOR_LIGHT,
|
20
|
-
DATE_TIME_COLOR,
|
21
21
|
EXPECTED_COLOR,
|
22
22
|
GRAY_COLOR,
|
23
23
|
LEVEL_COLOR,
|
24
|
+
RULE_COLOR,
|
24
25
|
WHITE_COLOR,
|
25
26
|
)
|
26
27
|
from logger_36.config.message import ACTUAL_PATTERNS, EXPECTED_PATTERNS, WHERE_SEPARATOR
|
27
28
|
from logger_36.constant.message import CONTEXT_LENGTH
|
28
|
-
from logger_36.task.format.rule import Rule
|
29
29
|
from logger_36.type.handler import handler_t as base_t
|
30
30
|
|
31
31
|
_COMMON_TRACEBACK_ARGUMENTS = ("theme", "width")
|
@@ -51,12 +51,7 @@ class console_rich_handler_t(base_t):
|
|
51
51
|
"""
|
52
52
|
|
53
53
|
def __init__(
|
54
|
-
self,
|
55
|
-
name: str | None,
|
56
|
-
message_width: int,
|
57
|
-
level: int,
|
58
|
-
formatter: l.Formatter | None,
|
59
|
-
kwargs,
|
54
|
+
self, name: str | None, message_width: int, level: int, kwargs
|
60
55
|
) -> None:
|
61
56
|
""""""
|
62
57
|
alternating_logs = kwargs.pop("alternating_logs", 0)
|
@@ -64,7 +59,7 @@ class console_rich_handler_t(base_t):
|
|
64
59
|
|
65
60
|
assert alternating_logs in (0, 1, 2)
|
66
61
|
|
67
|
-
base_t.__init__(self, name, message_width,
|
62
|
+
base_t.__init__(self, name, message_width, EscapedVersion, level, kwargs)
|
68
63
|
|
69
64
|
self.console = None # console_t | None.
|
70
65
|
self.alternating_logs = alternating_logs
|
@@ -96,21 +91,20 @@ class console_rich_handler_t(base_t):
|
|
96
91
|
name: str | None = None,
|
97
92
|
message_width: int = -1,
|
98
93
|
level: int = l.NOTSET,
|
99
|
-
formatter: l.Formatter | None = None,
|
100
94
|
**kwargs,
|
101
95
|
) -> h.Self:
|
102
96
|
""""""
|
103
|
-
return cls(name, message_width, level,
|
97
|
+
return cls(name, message_width, level, kwargs)
|
98
|
+
|
99
|
+
def Rule(self, text: str | None, /, *, color: str = "black") -> str | rule_t:
|
100
|
+
""""""
|
101
|
+
if text is None:
|
102
|
+
return rule_t(style=color)
|
103
|
+
return rule_t(title=text_t(text, style=f"bold {color}"), style=color)
|
104
104
|
|
105
105
|
def emit(self, record: l.LogRecord, /) -> None:
|
106
106
|
""""""
|
107
|
-
message, is_not_a_rule = self.MessageFromRecord(
|
108
|
-
record,
|
109
|
-
Rule,
|
110
|
-
line_width=self.message_width,
|
111
|
-
color=DATE_TIME_COLOR,
|
112
|
-
PreProcessed=EscapedVersion,
|
113
|
-
)
|
107
|
+
message, is_not_a_rule = self.MessageFromRecord(record, rule_color=RULE_COLOR)
|
114
108
|
if is_not_a_rule:
|
115
109
|
message = HighlightedVersion(
|
116
110
|
self.console,
|
@@ -126,10 +120,6 @@ class console_rich_handler_t(base_t):
|
|
126
120
|
""""""
|
127
121
|
self.console.print(message, crop=False, overflow="ignore")
|
128
122
|
|
129
|
-
def EmitRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
130
|
-
""""""
|
131
|
-
self.EmitAsIs(Rule(text, color))
|
132
|
-
|
133
123
|
|
134
124
|
def HighlightedVersion(
|
135
125
|
_: console_t,
|
@@ -8,7 +8,6 @@ import logging as l
|
|
8
8
|
import typing as h
|
9
9
|
from pathlib import Path as path_t
|
10
10
|
|
11
|
-
from logger_36.task.format.rule import RuleAsText
|
12
11
|
from logger_36.type.handler import file_handler_t as base_t
|
13
12
|
|
14
13
|
|
@@ -21,18 +20,15 @@ class file_handler_t(base_t):
|
|
21
20
|
name: str | None = None,
|
22
21
|
message_width: int = -1,
|
23
22
|
level: int = l.NOTSET,
|
24
|
-
formatter: l.Formatter | None = None,
|
25
23
|
path: str | path_t | None = None,
|
26
24
|
**_,
|
27
25
|
) -> h.Self:
|
28
26
|
""""""
|
29
|
-
return cls(name, message_width,
|
27
|
+
return cls(name, message_width, None, level, path)
|
30
28
|
|
31
29
|
def emit(self, record: l.LogRecord, /) -> None:
|
32
30
|
""""""
|
33
|
-
output = self.MessageFromRecord(
|
34
|
-
record, RuleAsText, line_width=self.message_width
|
35
|
-
)
|
31
|
+
output = self.MessageFromRecord(record)
|
36
32
|
self.stream.write(output[0] + "\n")
|
37
33
|
self.stream.flush()
|
38
34
|
|
@@ -10,28 +10,21 @@ import typing as h
|
|
10
10
|
from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
|
11
11
|
|
12
12
|
if RICH_IS_AVAILABLE:
|
13
|
-
from rich.console import Console as console_t
|
14
|
-
from rich.
|
15
|
-
from rich.
|
16
|
-
from rich.terminal_theme import DEFAULT_TERMINAL_THEME
|
13
|
+
from rich.console import Console as console_t
|
14
|
+
from rich.markup import escape as EscapedForRich
|
15
|
+
from rich.rule import Rule as rule_t
|
16
|
+
from rich.terminal_theme import DEFAULT_TERMINAL_THEME
|
17
|
+
from rich.text import Text as text_t
|
17
18
|
|
18
|
-
from logger_36.catalog.config.console_rich import
|
19
|
+
from logger_36.catalog.config.console_rich import RULE_COLOR
|
19
20
|
from logger_36.catalog.handler.console_rich import HighlightedVersion
|
20
21
|
else:
|
21
|
-
|
22
|
-
|
23
|
-
) =
|
22
|
+
console_t = EscapedForRich = rule_t = DEFAULT_TERMINAL_THEME = text_t = (
|
23
|
+
RULE_COLOR
|
24
|
+
) = HighlightedVersion = None
|
24
25
|
|
25
|
-
from logger_36.task.format.rule import Rule, RuleAsText
|
26
26
|
from logger_36.type.handler import handler_t as base_t
|
27
27
|
|
28
|
-
LogAsIs_h = h.Callable[[str | h.Any], None]
|
29
|
-
|
30
|
-
|
31
|
-
@h.runtime_checkable
|
32
|
-
class EmitRule_p(h.Protocol):
|
33
|
-
def __call__(self, /, *, text: str | None = None, color: str = "white") -> None: ...
|
34
|
-
|
35
28
|
|
36
29
|
class generic_handler_t(base_t):
|
37
30
|
"""
|
@@ -42,12 +35,7 @@ class generic_handler_t(base_t):
|
|
42
35
|
"""
|
43
36
|
|
44
37
|
def __init__(
|
45
|
-
self,
|
46
|
-
name: str | None,
|
47
|
-
message_width: int,
|
48
|
-
level: int,
|
49
|
-
formatter: l.Formatter | None,
|
50
|
-
kwargs,
|
38
|
+
self, name: str | None, message_width: int, level: int, kwargs
|
51
39
|
) -> None:
|
52
40
|
"""
|
53
41
|
EmitAsIs: By definition, the generic handler does not know how to output
|
@@ -59,12 +47,13 @@ class generic_handler_t(base_t):
|
|
59
47
|
|
60
48
|
assert alternating_logs in (0, 1, 2)
|
61
49
|
|
62
|
-
base_t.__init__(self, name, message_width,
|
50
|
+
base_t.__init__(self, name, message_width, None, level, kwargs)
|
63
51
|
|
64
52
|
if EmitAsIs is not None:
|
65
53
|
self.EmitAsIs = EmitAsIs
|
54
|
+
self.is_rich = False
|
66
55
|
self.console = None # console_t | None.
|
67
|
-
self.console_options = None #
|
56
|
+
self.console_options = None # rich.console.ConsoleOptions | None.
|
68
57
|
self.alternating_logs = alternating_logs
|
69
58
|
self._log_parity = False
|
70
59
|
|
@@ -73,11 +62,12 @@ class generic_handler_t(base_t):
|
|
73
62
|
def __post_init_local__(self, supports_html: bool) -> None:
|
74
63
|
""""""
|
75
64
|
if supports_html and (console_t is not None):
|
65
|
+
self.PreProcessedMessage = EscapedForRich
|
66
|
+
self.is_rich = True
|
76
67
|
self.console = console_t(highlight=False, force_terminal=True)
|
77
68
|
self.console_options = self.console.options.update(
|
78
69
|
overflow="ignore", no_wrap=True
|
79
70
|
)
|
80
|
-
self.EmitRule = self._EmitRichRule
|
81
71
|
|
82
72
|
@classmethod
|
83
73
|
def New(
|
@@ -87,25 +77,25 @@ class generic_handler_t(base_t):
|
|
87
77
|
name: str | None = None,
|
88
78
|
message_width: int = -1,
|
89
79
|
level: int = l.NOTSET,
|
90
|
-
formatter: l.Formatter | None = None,
|
91
80
|
**kwargs,
|
92
81
|
) -> h.Self:
|
93
82
|
""""""
|
94
|
-
return cls(name, message_width, level,
|
83
|
+
return cls(name, message_width, level, kwargs)
|
84
|
+
|
85
|
+
def Rule(self, text: str | None, /, *, color: str = "black") -> str | rule_t:
|
86
|
+
""""""
|
87
|
+
if self.is_rich:
|
88
|
+
if text is None:
|
89
|
+
return rule_t(style=color)
|
90
|
+
return rule_t(title=text_t(text, style=f"bold {color}"), style=color)
|
91
|
+
|
92
|
+
return base_t.Rule(self, text, color=color)
|
95
93
|
|
96
94
|
def emit(self, record: l.LogRecord, /) -> None:
|
97
95
|
""""""
|
98
|
-
if self.
|
99
|
-
message = self.MessageFromRecord(
|
100
|
-
record, RuleAsText, line_width=self.message_width
|
101
|
-
)[0]
|
102
|
-
else:
|
96
|
+
if self.is_rich:
|
103
97
|
message, is_not_a_rule = self.MessageFromRecord(
|
104
|
-
record,
|
105
|
-
Rule,
|
106
|
-
line_width=self.message_width,
|
107
|
-
color=DATE_TIME_COLOR,
|
108
|
-
PreProcessed=EscapedForRich,
|
98
|
+
record, rule_color=RULE_COLOR
|
109
99
|
)
|
110
100
|
if is_not_a_rule:
|
111
101
|
message = HighlightedVersion(
|
@@ -138,16 +128,12 @@ class generic_handler_t(base_t):
|
|
138
128
|
message = (
|
139
129
|
"<pre style='margin-bottom:0px'>" + "".join(html_segments) + "</pre>"
|
140
130
|
)
|
131
|
+
else:
|
132
|
+
message = self.MessageFromRecord(record)[0]
|
141
133
|
|
142
134
|
self.EmitAsIs(message)
|
143
135
|
self._log_parity = not self._log_parity
|
144
136
|
|
145
|
-
def _EmitRichRule(
|
146
|
-
self, /, *, text: str | None = None, color: str = "black"
|
147
|
-
) -> None:
|
148
|
-
""""""
|
149
|
-
self.EmitAsIs(Rule(text, color))
|
150
|
-
|
151
137
|
|
152
138
|
"""
|
153
139
|
COPYRIGHT NOTICE
|
@@ -4,31 +4,10 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
5
5
|
"""
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
""""""
|
12
|
-
if text is None:
|
13
|
-
return "---- ---- ---- ---- ---- ---- ---- ---- ----"
|
14
|
-
else:
|
15
|
-
return f"---- ---- ---- ---- {text} ---- ---- ---- ----"
|
16
|
-
|
17
|
-
|
18
|
-
if RICH_IS_AVAILABLE:
|
19
|
-
from rich.rule import Rule as rule_t # noqa
|
20
|
-
from rich.text import Text as text_t # noqa
|
21
|
-
|
22
|
-
def Rule(text: str | None, color: str, /) -> rule_t | str:
|
23
|
-
""""""
|
24
|
-
if text is None:
|
25
|
-
return rule_t(style=color)
|
26
|
-
else:
|
27
|
-
return rule_t(title=text_t(text, style=f"bold {color}"), style=color)
|
28
|
-
|
29
|
-
else:
|
30
|
-
rule_t = text_t = None
|
31
|
-
Rule = lambda _, __: RuleAsText(_, None)
|
7
|
+
RULE_CHARACTER = "-"
|
8
|
+
MIN_HALF_RULE_LENGTH = 4
|
9
|
+
DEFAULT_RULE_LENGTH = 50
|
10
|
+
DEFAULT_RULE = DEFAULT_RULE_LENGTH * RULE_CHARACTER
|
32
11
|
|
33
12
|
"""
|
34
13
|
COPYRIGHT NOTICE
|
logger_36/task/format/message.py
CHANGED
@@ -5,69 +5,10 @@ SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import difflib as diff
|
8
|
-
import logging as l
|
9
8
|
import typing as h
|
10
9
|
|
11
|
-
from logger_36.config.message import (
|
12
|
-
LEVEL_CLOSING,
|
13
|
-
LEVEL_OPENING,
|
14
|
-
MESSAGE_MARKER,
|
15
|
-
WHERE_SEPARATOR,
|
16
|
-
)
|
17
10
|
from logger_36.constant.generic import NOT_PASSED
|
18
|
-
from logger_36.constant.message import
|
19
|
-
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
20
|
-
from logger_36.extension.line import WrappedLines
|
21
|
-
from logger_36.type.message import RuleWithText_h
|
22
|
-
|
23
|
-
|
24
|
-
def MessageFromRecord(
|
25
|
-
record: l.LogRecord,
|
26
|
-
RuleWithText: RuleWithText_h,
|
27
|
-
/,
|
28
|
-
*,
|
29
|
-
line_width: int = 0,
|
30
|
-
color: str | None = None,
|
31
|
-
PreProcessed: h.Callable[[str], str] | None = None,
|
32
|
-
) -> tuple[str, bool]:
|
33
|
-
"""
|
34
|
-
See logger_36.catalog.handler.README.txt.
|
35
|
-
|
36
|
-
The second returned value is is_not_a_rule.
|
37
|
-
"""
|
38
|
-
message = record.msg
|
39
|
-
|
40
|
-
if hasattr(record, SHOW_W_RULE_ATTR):
|
41
|
-
return RuleWithText(message, color), False
|
42
|
-
|
43
|
-
if PreProcessed is not None:
|
44
|
-
message = PreProcessed(message)
|
45
|
-
if (line_width <= 0) or (message.__len__() <= line_width):
|
46
|
-
if "\n" in message:
|
47
|
-
message = NEXT_LINE_PROLOGUE.join(message.splitlines())
|
48
|
-
else:
|
49
|
-
if "\n" in message:
|
50
|
-
lines = WrappedLines(message.splitlines(), line_width)
|
51
|
-
else:
|
52
|
-
lines = WrappedLines([message], line_width)
|
53
|
-
message = NEXT_LINE_PROLOGUE.join(lines)
|
54
|
-
|
55
|
-
when_or_elapsed = getattr(record, "when_or_elapsed", None)
|
56
|
-
if when_or_elapsed is None:
|
57
|
-
return message, True
|
58
|
-
|
59
|
-
level_first_letter = getattr(record, "level_first_letter", "")
|
60
|
-
|
61
|
-
if (where := getattr(record, "where", None)) is None:
|
62
|
-
where = ""
|
63
|
-
else:
|
64
|
-
where = f"{NEXT_LINE_PROLOGUE}{WHERE_SEPARATOR} {where}"
|
65
|
-
|
66
|
-
return (
|
67
|
-
f"{when_or_elapsed}"
|
68
|
-
f"{LEVEL_OPENING}{level_first_letter}{LEVEL_CLOSING} "
|
69
|
-
f"{MESSAGE_MARKER} {message}{where}"
|
70
|
-
), True
|
11
|
+
from logger_36.constant.message import expected_op_h
|
71
12
|
|
72
13
|
|
73
14
|
def MessageWithActualExpected(
|
logger_36/type/handler.py
CHANGED
@@ -5,23 +5,38 @@ SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import logging as l
|
8
|
-
import sys as s
|
9
8
|
import typing as h
|
10
9
|
from pathlib import Path as path_t
|
11
10
|
|
12
|
-
from logger_36.config.message import
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
from logger_36.config.message import (
|
12
|
+
FALLBACK_MESSAGE_WIDTH,
|
13
|
+
LEVEL_CLOSING,
|
14
|
+
LEVEL_OPENING,
|
15
|
+
MESSAGE_MARKER,
|
16
|
+
WHERE_SEPARATOR,
|
17
|
+
)
|
18
|
+
from logger_36.constant.message import NEXT_LINE_PROLOGUE
|
19
|
+
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
20
|
+
from logger_36.constant.rule import (
|
21
|
+
DEFAULT_RULE,
|
22
|
+
DEFAULT_RULE_LENGTH,
|
23
|
+
MIN_HALF_RULE_LENGTH,
|
24
|
+
RULE_CHARACTER,
|
25
|
+
)
|
26
|
+
from logger_36.extension.line import WrappedLines
|
27
|
+
|
28
|
+
|
29
|
+
class extension_t:
|
30
|
+
def __init__(
|
31
|
+
self,
|
32
|
+
name: str | None,
|
33
|
+
message_width: int,
|
34
|
+
PreProcessedMessage: h.Callable[[str], str] | None,
|
35
|
+
) -> None:
|
20
36
|
""""""
|
21
37
|
self.name = name
|
22
38
|
self.message_width = message_width
|
23
|
-
|
24
|
-
self.MessageFromRecord: MessageFromRecord_h | None = None
|
39
|
+
self.PreProcessedMessage = PreProcessedMessage
|
25
40
|
|
26
41
|
self.__post_init__()
|
27
42
|
|
@@ -40,37 +55,95 @@ class _base_t:
|
|
40
55
|
"""
|
41
56
|
raise NotImplementedError
|
42
57
|
|
58
|
+
def MessageFromRecord(
|
59
|
+
self, record: l.LogRecord, /, *, rule_color: str | None = None
|
60
|
+
) -> tuple[str, bool]:
|
61
|
+
"""
|
62
|
+
The second returned value is is_not_a_rule.
|
63
|
+
"""
|
64
|
+
message = record.msg # See logger_36.catalog.handler.README.txt.
|
65
|
+
if self.PreProcessedMessage is not None:
|
66
|
+
message = self.PreProcessedMessage(message)
|
67
|
+
|
68
|
+
if hasattr(record, SHOW_W_RULE_ATTR):
|
69
|
+
return self.Rule(message, color=rule_color), False
|
70
|
+
|
71
|
+
if (self.message_width <= 0) or (message.__len__() <= self.message_width):
|
72
|
+
if "\n" in message:
|
73
|
+
message = NEXT_LINE_PROLOGUE.join(message.splitlines())
|
74
|
+
else:
|
75
|
+
if "\n" in message:
|
76
|
+
lines = WrappedLines(message.splitlines(), self.message_width)
|
77
|
+
else:
|
78
|
+
lines = WrappedLines([message], self.message_width)
|
79
|
+
message = NEXT_LINE_PROLOGUE.join(lines)
|
80
|
+
|
81
|
+
when_or_elapsed = getattr(record, "when_or_elapsed", None)
|
82
|
+
if when_or_elapsed is None:
|
83
|
+
return message, True
|
84
|
+
|
85
|
+
if (where := getattr(record, "where", None)) is None:
|
86
|
+
where = ""
|
87
|
+
else:
|
88
|
+
where = f"{NEXT_LINE_PROLOGUE}{WHERE_SEPARATOR} {where}"
|
89
|
+
|
90
|
+
return (
|
91
|
+
f"{when_or_elapsed}"
|
92
|
+
f"{LEVEL_OPENING}{record.levelname[0]}{LEVEL_CLOSING} "
|
93
|
+
f"{MESSAGE_MARKER} {message}{where}"
|
94
|
+
), True
|
95
|
+
|
96
|
+
def Rule(self, text: str | None, /, *, color: str = "black") -> str | h.Any:
|
97
|
+
"""
|
98
|
+
Return type hint h.Any: For Rich, for example.
|
99
|
+
"""
|
100
|
+
if text is None:
|
101
|
+
if self.message_width > 0:
|
102
|
+
return self.message_width * RULE_CHARACTER
|
103
|
+
return DEFAULT_RULE
|
104
|
+
|
105
|
+
if self.message_width > 0:
|
106
|
+
target_width = self.message_width
|
107
|
+
else:
|
108
|
+
target_width = DEFAULT_RULE_LENGTH
|
109
|
+
half_rule_length = max(
|
110
|
+
(target_width - text.__len__() - 2) // 2, MIN_HALF_RULE_LENGTH
|
111
|
+
)
|
112
|
+
half_rule = half_rule_length * RULE_CHARACTER
|
113
|
+
|
114
|
+
return f"{half_rule} {text} {half_rule}"
|
115
|
+
|
43
116
|
def EmitAsIs(self, message: str, /) -> None:
|
44
117
|
""""""
|
45
|
-
|
118
|
+
raise NotImplementedError
|
46
119
|
|
47
120
|
def EmitRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
48
121
|
""""""
|
49
|
-
self.EmitAsIs(
|
122
|
+
self.EmitAsIs(self.Rule(text, color=color))
|
50
123
|
|
51
124
|
|
52
|
-
class handler_t(l.Handler,
|
125
|
+
class handler_t(l.Handler, extension_t):
|
53
126
|
def __init__(
|
54
127
|
self,
|
55
128
|
name: str | None,
|
56
129
|
message_width: int,
|
130
|
+
PreProcessedMessage: h.Callable[[str], str] | None,
|
57
131
|
level: int,
|
58
|
-
formatter: l.Formatter | None,
|
59
132
|
*_,
|
60
133
|
) -> None:
|
61
134
|
""""""
|
62
135
|
l.Handler.__init__(self)
|
63
|
-
|
64
|
-
__post_init__(self, level
|
136
|
+
extension_t.__init__(self, name, message_width, PreProcessedMessage)
|
137
|
+
__post_init__(self, level)
|
65
138
|
|
66
139
|
|
67
|
-
class file_handler_t(l.FileHandler,
|
140
|
+
class file_handler_t(l.FileHandler, extension_t):
|
68
141
|
def __init__(
|
69
142
|
self,
|
70
143
|
name: str | None,
|
71
144
|
message_width: int,
|
145
|
+
PreProcessedMessage: h.Callable[[str], str] | None,
|
72
146
|
level: int,
|
73
|
-
formatter: l.Formatter | None,
|
74
147
|
path: str | path_t | None,
|
75
148
|
*_,
|
76
149
|
) -> None:
|
@@ -83,38 +156,17 @@ class file_handler_t(l.FileHandler, _base_t):
|
|
83
156
|
raise ValueError(f"File or folder already exists: {path}.")
|
84
157
|
|
85
158
|
l.FileHandler.__init__(self, path)
|
86
|
-
|
87
|
-
__post_init__(self, level
|
159
|
+
extension_t.__init__(self, name, message_width, PreProcessedMessage)
|
160
|
+
__post_init__(self, level)
|
88
161
|
|
89
162
|
|
90
163
|
any_handler_t = handler_t | file_handler_t
|
91
164
|
|
92
165
|
|
93
|
-
def __post_init__(
|
94
|
-
handler: any_handler_t, level: int, formatter: l.Formatter | None
|
95
|
-
) -> None:
|
166
|
+
def __post_init__(handler: any_handler_t, level: int) -> None:
|
96
167
|
""""""
|
97
168
|
handler.setLevel(level)
|
98
169
|
|
99
|
-
if formatter is None:
|
100
|
-
handler.MessageFromRecord = MessageFromRecord
|
101
|
-
else:
|
102
|
-
handler.setFormatter(formatter)
|
103
|
-
_MessageFromRecordRaw = handler.formatter.format
|
104
|
-
|
105
|
-
def _MessageFromRecord(
|
106
|
-
record: l.LogRecord,
|
107
|
-
_: RuleWithText_h,
|
108
|
-
/,
|
109
|
-
*,
|
110
|
-
line_width: int = 0,
|
111
|
-
PreProcessed: h.Callable[[str], str] | None = None,
|
112
|
-
) -> tuple[str, bool]:
|
113
|
-
#
|
114
|
-
return _MessageFromRecordRaw(record), False
|
115
|
-
|
116
|
-
handler.MessageFromRecord = _MessageFromRecord
|
117
|
-
|
118
170
|
|
119
171
|
"""
|
120
172
|
COPYRIGHT NOTICE
|
logger_36/type/logger.py
CHANGED
@@ -38,12 +38,12 @@ from logger_36.constant.memory import UNKNOWN_MEMORY_USAGE
|
|
38
38
|
from logger_36.constant.message import LINE_INDENT, TIME_LENGTH_m_1, expected_op_h
|
39
39
|
from logger_36.constant.path import PROJECT_FILE_RELATIVE, USER_FOLDER
|
40
40
|
from logger_36.constant.record import SHOW_W_RULE_ATTR, SHOW_WHERE_ATTR
|
41
|
-
from logger_36.task.format.message import
|
42
|
-
from logger_36.task.format.rule import RuleAsText
|
41
|
+
from logger_36.task.format.message import MessageWithActualExpected
|
43
42
|
from logger_36.task.measure.chronos import ElapsedTime
|
44
43
|
from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
|
45
44
|
from logger_36.task.measure.memory import CurrentUsage as CurrentMemoryUsage
|
46
45
|
from logger_36.type.handler import any_handler_t as base_handler_t
|
46
|
+
from logger_36.type.handler import extension_t as handler_extension_t
|
47
47
|
from logger_36.type.issue import NewIssue, issue_t
|
48
48
|
|
49
49
|
if RICH_IS_AVAILABLE:
|
@@ -98,9 +98,10 @@ class logger_t(base_t):
|
|
98
98
|
init=False, default_factory=dict
|
99
99
|
)
|
100
100
|
intercepts_exceptions: bool = d.field(init=False, default=False)
|
101
|
-
_on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list)
|
102
101
|
_should_hold_messages: bool = d.field(init=False, default=True)
|
103
102
|
_should_activate_log_interceptions: bool = d.field(init=False, default=False)
|
103
|
+
_on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list)
|
104
|
+
_recording_handler: handler_extension_t | None = d.field(init=False, default=None)
|
104
105
|
|
105
106
|
name_: d.InitVar[str | None] = None
|
106
107
|
level_: d.InitVar[int] = l.NOTSET
|
@@ -164,8 +165,11 @@ class logger_t(base_t):
|
|
164
165
|
self.setLevel(level_)
|
165
166
|
self.propagate = False # Part of base_t.
|
166
167
|
|
167
|
-
|
168
|
-
self.
|
168
|
+
if self.should_record_messages:
|
169
|
+
self.ActivateMessageRecording()
|
170
|
+
|
171
|
+
for level_id in l.getLevelNamesMapping().values():
|
172
|
+
self.events[level_id] = 0
|
169
173
|
|
170
174
|
if activate_wrn_interceptions:
|
171
175
|
self.ToggleWarningInterceptions(True)
|
@@ -190,35 +194,10 @@ class logger_t(base_t):
|
|
190
194
|
elapsed_time, now = ElapsedTime(should_return_now=True)
|
191
195
|
|
192
196
|
if (self._on_hold.__len__() > 0) and not self._should_hold_messages:
|
193
|
-
|
194
|
-
if self.should_record_messages:
|
195
|
-
self.recorded.append(
|
196
|
-
(held.levelno, MessageFromRecord(held, RuleAsText)[0])
|
197
|
-
)
|
198
|
-
base_t.handle(self, held)
|
199
|
-
self._on_hold.clear()
|
197
|
+
self._FlushRecordsOnHold()
|
200
198
|
|
201
199
|
if (date := now.date()) != self.last_message_date:
|
202
|
-
self.
|
203
|
-
date_record = l.makeLogRecord(
|
204
|
-
{
|
205
|
-
"name": self.name,
|
206
|
-
"levelno": l.INFO, # For management by logging.Logger.handle.
|
207
|
-
"msg": f"DATE: {date.strftime(DATE_FORMAT)}",
|
208
|
-
SHOW_W_RULE_ATTR: True,
|
209
|
-
}
|
210
|
-
)
|
211
|
-
if self._should_hold_messages:
|
212
|
-
self._on_hold.append(date_record)
|
213
|
-
else:
|
214
|
-
if self.should_record_messages:
|
215
|
-
self.recorded.append(
|
216
|
-
(
|
217
|
-
date_record.levelno,
|
218
|
-
MessageFromRecord(date_record, RuleAsText)[0],
|
219
|
-
)
|
220
|
-
)
|
221
|
-
base_t.handle(self, date_record)
|
200
|
+
self._AcknowledgeDateChange(date)
|
222
201
|
|
223
202
|
# When.
|
224
203
|
if now - self.last_message_now > LONG_ENOUGH:
|
@@ -246,9 +225,6 @@ class logger_t(base_t):
|
|
246
225
|
else:
|
247
226
|
where = None
|
248
227
|
|
249
|
-
# How.
|
250
|
-
record.level_first_letter = record.levelname[0]
|
251
|
-
|
252
228
|
# What.
|
253
229
|
if not isinstance(record.msg, str):
|
254
230
|
record.msg = str(record.msg)
|
@@ -256,11 +232,11 @@ class logger_t(base_t):
|
|
256
232
|
if self._should_hold_messages:
|
257
233
|
self._on_hold.append(record)
|
258
234
|
else:
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
235
|
+
self._HandleRecord(record)
|
236
|
+
self.events[record.levelno] += 1
|
237
|
+
|
238
|
+
if self.should_watch_memory_usage:
|
239
|
+
self.memory_usages.append((where, CurrentMemoryUsage()))
|
264
240
|
|
265
241
|
if (self.exit_on_critical and (record.levelno is l.CRITICAL)) or (
|
266
242
|
self.exit_on_error and (record.levelno is l.ERROR)
|
@@ -269,34 +245,49 @@ class logger_t(base_t):
|
|
269
245
|
# __post_init__ set self.exit_on_critical if self.exit_on_error.
|
270
246
|
s.exit(1)
|
271
247
|
|
272
|
-
|
248
|
+
def _FlushRecordsOnHold(self) -> None:
|
249
|
+
""""""
|
250
|
+
for held in self._on_hold:
|
251
|
+
self._HandleRecord(held)
|
273
252
|
|
274
|
-
|
275
|
-
self.memory_usages.append((where, CurrentMemoryUsage()))
|
253
|
+
self._on_hold.clear()
|
276
254
|
|
277
|
-
def
|
255
|
+
def _AcknowledgeDateChange(self, date: date_t, /) -> None:
|
278
256
|
""""""
|
279
|
-
self.
|
257
|
+
self.last_message_date = date
|
258
|
+
|
259
|
+
record = l.makeLogRecord(
|
260
|
+
{
|
261
|
+
"name": self.name,
|
262
|
+
"levelno": l.INFO, # For management by logging.Logger.handle.
|
263
|
+
"msg": f"DATE: {date.strftime(DATE_FORMAT)}",
|
264
|
+
SHOW_W_RULE_ATTR: True,
|
265
|
+
}
|
266
|
+
)
|
280
267
|
|
281
|
-
|
268
|
+
if self._should_hold_messages:
|
269
|
+
self._on_hold.append(record)
|
270
|
+
else:
|
271
|
+
self._HandleRecord(record)
|
272
|
+
|
273
|
+
def _HandleRecord(self, record: l.LogRecord, /) -> None:
|
282
274
|
""""""
|
283
|
-
if
|
284
|
-
|
275
|
+
if self.should_record_messages:
|
276
|
+
message = self._recording_handler.MessageFromRecord(record)[0]
|
277
|
+
self.recorded.append((record.levelno, message))
|
285
278
|
|
286
|
-
|
287
|
-
handler_kwargs = {}
|
288
|
-
else:
|
289
|
-
handler_kwargs = {"alternating_logs": alternating_logs}
|
290
|
-
self.AddHandler(console_rich_handler_t, **handler_kwargs)
|
279
|
+
base_t.handle(self, record)
|
291
280
|
|
292
|
-
def
|
281
|
+
def ActivateMessageRecording(self) -> None:
|
293
282
|
""""""
|
294
|
-
self.
|
283
|
+
self._recording_handler = handler_extension_t("recording_handler", 0, None)
|
284
|
+
self.should_record_messages = True # Useless if called from __post_init__.
|
285
|
+
self.info(f'Message recording activated for logger "{self.name}"')
|
295
286
|
|
296
287
|
def ResetEventCounts(self) -> None:
|
297
288
|
""""""
|
298
|
-
for
|
299
|
-
self.events[
|
289
|
+
for level_id in self.events:
|
290
|
+
self.events[level_id] = 0
|
300
291
|
|
301
292
|
def ToggleWarningInterceptions(self, state: bool, /) -> None:
|
302
293
|
""""""
|
@@ -373,27 +364,17 @@ class logger_t(base_t):
|
|
373
364
|
self.intercepts_exceptions = False
|
374
365
|
self.info("Exception Interception: OFF")
|
375
366
|
|
376
|
-
def DealWithException(self, _, exc_value, exc_traceback, /) -> None:
|
377
|
-
""""""
|
378
|
-
exception = exc_value.with_traceback(exc_traceback)
|
379
|
-
self.LogException(exception, level=l.CRITICAL)
|
380
|
-
s.exit(1)
|
381
|
-
|
382
|
-
def DealWithExceptionInThread(
|
383
|
-
self, exc_type, exc_value, exc_traceback, _, /
|
384
|
-
) -> None:
|
385
|
-
""""""
|
386
|
-
self.DealWithException(exc_type, exc_value, exc_traceback)
|
387
|
-
|
388
367
|
def AddHandler(
|
389
368
|
self,
|
390
|
-
|
369
|
+
handler_t_or_handler: type[base_handler_t]
|
370
|
+
| base_handler_t
|
371
|
+
| l.Handler
|
372
|
+
| l.FileHandler,
|
391
373
|
/,
|
392
374
|
*,
|
393
375
|
name: str | None = None,
|
394
376
|
level: int = l.INFO,
|
395
377
|
message_width: int = -1,
|
396
|
-
formatter: l.Formatter | None = None,
|
397
378
|
should_still_hold_messages: bool = False,
|
398
379
|
**kwargs,
|
399
380
|
) -> None:
|
@@ -404,13 +385,12 @@ class logger_t(base_t):
|
|
404
385
|
|
405
386
|
self._should_hold_messages = should_still_hold_messages
|
406
387
|
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
)
|
388
|
+
if isinstance(handler_t_or_handler, type):
|
389
|
+
handler = handler_t_or_handler.New(
|
390
|
+
name=name, message_width=message_width, level=level, **kwargs
|
391
|
+
)
|
392
|
+
else:
|
393
|
+
handler = handler_t_or_handler
|
414
394
|
base_t.addHandler(self, handler)
|
415
395
|
|
416
396
|
path = getattr(handler, "baseFilename", "")
|
@@ -421,6 +401,25 @@ class logger_t(base_t):
|
|
421
401
|
f"level {handler.level}={l.getLevelName(handler.level)}{path}"
|
422
402
|
)
|
423
403
|
|
404
|
+
def MakeMonochrome(self) -> None:
|
405
|
+
""""""
|
406
|
+
self.AddHandler(console_handler_t)
|
407
|
+
|
408
|
+
def MakeRich(self, *, alternating_logs: int = 0) -> None:
|
409
|
+
""""""
|
410
|
+
if MISSING_RICH_MESSAGE is not None:
|
411
|
+
s.__stderr__.write(MISSING_RICH_MESSAGE + "\n")
|
412
|
+
|
413
|
+
if console_rich_handler_t is console_handler_t:
|
414
|
+
handler_kwargs = {}
|
415
|
+
else:
|
416
|
+
handler_kwargs = {"alternating_logs": alternating_logs}
|
417
|
+
self.AddHandler(console_rich_handler_t, **handler_kwargs)
|
418
|
+
|
419
|
+
def MakePermanent(self, path: str | path_t, /) -> None:
|
420
|
+
""""""
|
421
|
+
self.AddHandler(file_handler_t, path=path)
|
422
|
+
|
424
423
|
def __call__(self, *args, **kwargs) -> None:
|
425
424
|
"""
|
426
425
|
For a print-like calling for print-based debugging.
|
@@ -483,13 +482,26 @@ class logger_t(base_t):
|
|
483
482
|
message = f"Exception of type {type(exception).__name__}\n----\n{formatted}"
|
484
483
|
self.log(level, message, extra={SHOW_WHERE_ATTR: False})
|
485
484
|
|
485
|
+
def DealWithException(self, _, exc_value, exc_traceback, /) -> None:
|
486
|
+
""""""
|
487
|
+
exception = exc_value.with_traceback(exc_traceback)
|
488
|
+
self.LogException(exception, level=l.CRITICAL)
|
489
|
+
s.exit(1)
|
490
|
+
|
491
|
+
def DealWithExceptionInThread(
|
492
|
+
self, exc_type, exc_value, exc_traceback, _, /
|
493
|
+
) -> None:
|
494
|
+
""""""
|
495
|
+
self.DealWithException(exc_type, exc_value, exc_traceback)
|
496
|
+
|
486
497
|
def LogAsIs(self, message: str, /, *, indented: bool = False) -> None:
|
487
498
|
""""""
|
488
499
|
if indented:
|
489
500
|
message = text.indent(message, LINE_INDENT)
|
490
501
|
|
491
502
|
for handler in self.handlers:
|
492
|
-
handler
|
503
|
+
if (EmitAsIs := getattr(handler, "EmitAsIs", None)) is not None:
|
504
|
+
EmitAsIs(message)
|
493
505
|
|
494
506
|
info_raw = LogAsIs # To follow the convention of the logging methods info, error...
|
495
507
|
|
@@ -498,7 +510,8 @@ class logger_t(base_t):
|
|
498
510
|
) -> None:
|
499
511
|
""""""
|
500
512
|
for handler in self.handlers:
|
501
|
-
|
513
|
+
if (EmitRule := getattr(handler, "EmitRule", None)) is not None:
|
514
|
+
EmitRule(text=message, color=color)
|
502
515
|
|
503
516
|
def AddContextLevel(self, new_level: str, /) -> None:
|
504
517
|
""""""
|
logger_36/version.py
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
logger_36/__init__.py,sha256=mK6AD0eWI2Sk42oxleTvsxzYJ28FbHK5WNkpLgAhnNE,2129
|
2
|
-
logger_36/version.py,sha256=
|
3
|
-
logger_36/api/content.py,sha256=
|
2
|
+
logger_36/version.py,sha256=vDO1d9-QYkQ8yZUGGG46kdG9NRQx6ONSvh6-E6JGHu4,1680
|
3
|
+
logger_36/api/content.py,sha256=DuT4UX4r_1DTXzuuRD-tvsTZk5X-Nj11loBKhuWOMw0,1791
|
4
4
|
logger_36/api/gpu.py,sha256=NNs1IvQ7bh8Dppm8O8K2YLWbm4rogc3Ie_-D6xzkX3g,1726
|
5
5
|
logger_36/api/memory.py,sha256=vOY4cTTrC3u7L0OrKXdPNlsCahYjCrY4h7iqpGZv9kU,2217
|
6
6
|
logger_36/api/storage.py,sha256=RYjn2TD-E1zfNTMgm4b2mbYNVtTwsCUMbuPlMbuvgP0,1774
|
7
7
|
logger_36/api/system.py,sha256=h-3GfhZPwawv0UKBWKkT1LzxSCZwpA2VIsy03lLYi6w,1725
|
8
8
|
logger_36/api/time.py,sha256=JG0vgzPSRZ7UWQyoihnVu4sjPC-okFIKA3ZyNh2GaZo,1798
|
9
9
|
logger_36/api/type.py,sha256=eLZ2yuH-sYeh4Z2KnAwTRJEbmkmgzBPMncdqXfFUTG8,1760
|
10
|
-
logger_36/catalog/config/console_rich.py,sha256=
|
10
|
+
logger_36/catalog/config/console_rich.py,sha256=t9p9-AkSgPiLAsm1evAdbz77g7JcVLePhUJ1FzNi3cY,2330
|
11
11
|
logger_36/catalog/config/optional.py,sha256=5vabOlEQIFxoT_y4AjP19rpOjBuUJplpuBkLoCIKImA,1872
|
12
|
-
logger_36/catalog/handler/console.py,sha256=
|
13
|
-
logger_36/catalog/handler/console_rich.py,sha256=
|
14
|
-
logger_36/catalog/handler/file.py,sha256=
|
15
|
-
logger_36/catalog/handler/generic.py,sha256=
|
12
|
+
logger_36/catalog/handler/console.py,sha256=OKtRG3PseT06_UwZBtbragNIKvCqa7ZsLphYEsgeq2c,2308
|
13
|
+
logger_36/catalog/handler/console_rich.py,sha256=b3B_pQefv0IeQFEj-tZ5-tH8RrcessZI8sI4Tyf17bg,6180
|
14
|
+
logger_36/catalog/handler/file.py,sha256=JReN8KruN8eKhBfG9sj72kkHfukHK4-8mdSxNpgFhLU,2455
|
15
|
+
logger_36/catalog/handler/generic.py,sha256=0Z4Vm-AAc92szghYEzihkm9CBRzCvqgdUTXH_p98S4o,6314
|
16
16
|
logger_36/catalog/logger/chronos.py,sha256=S4m9TMPQy_Ju500mpE1jNzu2gZG-QKdVuvX9RVRKHR8,1911
|
17
17
|
logger_36/catalog/logger/gpu.py,sha256=Py5YY0nD_pqJzJsEKQYoOGHcPqyNVJ3J2noOS3hDL6g,2890
|
18
18
|
logger_36/catalog/logger/memory.py,sha256=J0ZGKO7j1FZA_aDGxpABtvzDy1RjCDiDmWYh4U98fEI,4253
|
@@ -30,6 +30,7 @@ logger_36/constant/memory.py,sha256=Q_E5tTWa-cGaNwrE_xmKa3BxQG6oJO6DHczrxc_M4sE,
|
|
30
30
|
logger_36/constant/message.py,sha256=YJOEzdI0ZjUOdHo3CsiS56FVPhrfNoQYvXuUkprH61g,2312
|
31
31
|
logger_36/constant/path.py,sha256=OfLh70Jyc8po9Ls34nQh_bRr3PXyQ3kF9ciR9QPhiqI,2213
|
32
32
|
logger_36/constant/record.py,sha256=gQCGLxq8Vs789Ty_qaRNKy18mqlyMT_4kyN-T9r_rGE,1734
|
33
|
+
logger_36/constant/rule.py,sha256=tBKQgPTt6G_p5eInDdWoEEAvQFz4WMSt5THsS5jvk14,1779
|
33
34
|
logger_36/constant/system.py,sha256=pLlLXG5sepQlSUOo3TphaGrHg8xzJBp-GxpL2NPP47k,1904
|
34
35
|
logger_36/extension/html_.py,sha256=W9SyiYsaaYHUrHLGAAN2wiJGXUlwOBJ5gzdjmEcnF18,3342
|
35
36
|
logger_36/extension/line.py,sha256=joeojQX1bZJM53333mOEU3s-YC5ExGOrN9Cu9Lh5-FU,2617
|
@@ -38,16 +39,14 @@ logger_36/instance/loggers.py,sha256=inBk4KKrQ-z3szaopQ29-qQwh1iSc842sWo5J6zJoiM
|
|
38
39
|
logger_36/task/inspection.py,sha256=ZgPcrPo3h_kEnM-UpHDLg7PAFfB2fqsLFdfmi6hlPVA,4484
|
39
40
|
logger_36/task/storage.py,sha256=KAILmJlF5IULxEX9QRCyXCwcalp5mpunWVh1oXuLvSs,3516
|
40
41
|
logger_36/task/format/memory.py,sha256=J1Oy3jw8wjSp2kuiRUm_VFpzXOHX2FOc7nuRrCyrskw,3723
|
41
|
-
logger_36/task/format/message.py,sha256=
|
42
|
-
logger_36/task/format/rule.py,sha256=4wQpeBBbCeF13rXl3Q9UEvvYh4sJOFfk6hOvJHDXYvY,2384
|
42
|
+
logger_36/task/format/message.py,sha256=Rm6zymVEEGcgKfmxMPXP7q3PtwZJKlXGhqZ5tnvlwxA,3502
|
43
43
|
logger_36/task/measure/chronos.py,sha256=7ijMZgP4EP18HbLV2yCxpNpRS9724Wyk523f-nkbhUM,2529
|
44
44
|
logger_36/task/measure/memory.py,sha256=kkPHEIUTUhkCOLrAt01eLJLnsnkl0nFPNhFZdIB_JAw,1991
|
45
|
-
logger_36/type/handler.py,sha256=
|
45
|
+
logger_36/type/handler.py,sha256=ChxP1j9PXLmoiNcsOdxI4bYVdr75v7HeCWp_iYJ2WNY,6602
|
46
46
|
logger_36/type/issue.py,sha256=QHAYf7QgrjJUtF2D46z6X630qTgeP_0FE5hIwf54RsE,2688
|
47
|
-
logger_36/type/logger.py,sha256=
|
47
|
+
logger_36/type/logger.py,sha256=tWdexeJT9IrxKK2NQmnHi1WVmN16xR8RNZPMc__SWBs,25447
|
48
48
|
logger_36/type/loggers.py,sha256=7EX7Sg_RlduBjdfFlNZmUfNeDloH1xU30Rdkg_-rXh8,3172
|
49
|
-
logger_36/
|
50
|
-
logger_36-2025.
|
51
|
-
logger_36-2025.
|
52
|
-
logger_36-2025.
|
53
|
-
logger_36-2025.18.dist-info/RECORD,,
|
49
|
+
logger_36-2025.20.dist-info/METADATA,sha256=On7rI0r81M6ehWSyX7ZPiBKYVZoLqMPj-1VJWRuSd50,6529
|
50
|
+
logger_36-2025.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
51
|
+
logger_36-2025.20.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
|
52
|
+
logger_36-2025.20.dist-info/RECORD,,
|
logger_36/type/message.py
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Copyright CNRS (https://www.cnrs.fr/index.php/en)
|
3
|
-
Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
|
4
|
-
SEE COPYRIGHT NOTICE BELOW
|
5
|
-
"""
|
6
|
-
|
7
|
-
import logging as l
|
8
|
-
import typing as h
|
9
|
-
|
10
|
-
from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
|
11
|
-
|
12
|
-
|
13
|
-
@h.runtime_checkable
|
14
|
-
class _RuleAsText_p(h.Protocol):
|
15
|
-
def __call__(self, text: str | None, color: None, /) -> str: ...
|
16
|
-
|
17
|
-
|
18
|
-
if RICH_IS_AVAILABLE:
|
19
|
-
from rich.rule import Rule as rule_t # noqa
|
20
|
-
|
21
|
-
@h.runtime_checkable
|
22
|
-
class _Rule_p(h.Protocol):
|
23
|
-
def __call__(self, text: str | None, color: str, /) -> rule_t | str: ...
|
24
|
-
else:
|
25
|
-
_Rule_p = None
|
26
|
-
|
27
|
-
RuleWithText_h = _RuleAsText_p | _Rule_p
|
28
|
-
|
29
|
-
|
30
|
-
@h.runtime_checkable
|
31
|
-
class _MessageFromRecordPreprocessed_p(h.Protocol):
|
32
|
-
def __call__(
|
33
|
-
self,
|
34
|
-
record: l.LogRecord,
|
35
|
-
RuleWithText: RuleWithText_h,
|
36
|
-
/,
|
37
|
-
*,
|
38
|
-
line_width: int = 0,
|
39
|
-
PreProcessed: h.Callable[[str], str] | None = None,
|
40
|
-
) -> tuple[str, bool]: ...
|
41
|
-
|
42
|
-
|
43
|
-
MessageFromRecord_h = _MessageFromRecordPreprocessed_p
|
44
|
-
|
45
|
-
|
46
|
-
"""
|
47
|
-
COPYRIGHT NOTICE
|
48
|
-
|
49
|
-
This software is governed by the CeCILL license under French law and
|
50
|
-
abiding by the rules of distribution of free software. You can use,
|
51
|
-
modify and/ or redistribute the software under the terms of the CeCILL
|
52
|
-
license as circulated by CEA, CNRS and INRIA at the following URL
|
53
|
-
"http://www.cecill.info".
|
54
|
-
|
55
|
-
As a counterpart to the access to the source code and rights to copy,
|
56
|
-
modify and redistribute granted by the license, users are provided only
|
57
|
-
with a limited warranty and the software's author, the holder of the
|
58
|
-
economic rights, and the successive licensors have only limited
|
59
|
-
liability.
|
60
|
-
|
61
|
-
In this respect, the user's attention is drawn to the risks associated
|
62
|
-
with loading, using, modifying and/or developing or reproducing the
|
63
|
-
software by the user in light of its specific status of free software,
|
64
|
-
that may mean that it is complicated to manipulate, and that also
|
65
|
-
therefore means that it is reserved for developers and experienced
|
66
|
-
professionals having in-depth computer knowledge. Users are therefore
|
67
|
-
encouraged to load and test the software's suitability as regards their
|
68
|
-
requirements in conditions enabling the security of their systems and/or
|
69
|
-
data to be ensured and, more generally, to use and operate it in the
|
70
|
-
same conditions as regards security.
|
71
|
-
|
72
|
-
The fact that you are presently reading this means that you have had
|
73
|
-
knowledge of the CeCILL license and that you accept its terms.
|
74
|
-
|
75
|
-
SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
|
76
|
-
"""
|
File without changes
|
File without changes
|