logger-36 2025.7__py3-none-any.whl → 2025.9__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/storage.py +1 -1
- logger_36/catalog/handler/console.py +3 -2
- logger_36/catalog/handler/console_rich.py +10 -1
- logger_36/catalog/handler/file.py +3 -3
- logger_36/catalog/handler/generic.py +1 -1
- logger_36/catalog/logger/gpu.py +1 -1
- logger_36/exception.py +2 -3
- logger_36/extension/html_.py +107 -0
- logger_36/handler.py +1 -1
- logger_36/task/storage.py +10 -77
- logger_36/type/handler.py +1 -1
- logger_36/type/logger.py +63 -62
- logger_36/version.py +1 -1
- {logger_36-2025.7.dist-info → logger_36-2025.9.dist-info}/METADATA +1 -1
- {logger_36-2025.7.dist-info → logger_36-2025.9.dist-info}/RECORD +17 -16
- {logger_36-2025.7.dist-info → logger_36-2025.9.dist-info}/WHEEL +0 -0
- {logger_36-2025.7.dist-info → logger_36-2025.9.dist-info}/top_level.txt +0 -0
logger_36/api/storage.py
CHANGED
@@ -6,6 +6,7 @@ SEE COPYRIGHT NOTICE BELOW
|
|
6
6
|
|
7
7
|
import dataclasses as d
|
8
8
|
import logging as l
|
9
|
+
import sys as s
|
9
10
|
import typing as h
|
10
11
|
|
11
12
|
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
@@ -58,14 +59,14 @@ class console_handler_t(l.Handler):
|
|
58
59
|
message = RuleAsText(record.msg)
|
59
60
|
else:
|
60
61
|
message = self.MessageFromRecord(record)
|
61
|
-
|
62
|
+
s.__stdout__.write(message + "\n")
|
62
63
|
|
63
64
|
def LogAsIs(self, message: str, /) -> None:
|
64
65
|
"""
|
65
66
|
See documentation of
|
66
67
|
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
67
68
|
"""
|
68
|
-
|
69
|
+
s.__stdout__.write(message + "\n")
|
69
70
|
|
70
71
|
def DisplayRule(self, /, *, text: str | None = None, color: str = "white") -> None:
|
71
72
|
""""""
|
@@ -69,11 +69,20 @@ class console_rich_handler_t(l.Handler):
|
|
69
69
|
should_store_memory_usage: d.InitVar[bool] = False
|
70
70
|
message_width: d.InitVar[int] = -1
|
71
71
|
formatter: d.InitVar[l.Formatter | None] = None
|
72
|
+
#
|
72
73
|
should_install_traceback: d.InitVar[bool] = False
|
73
74
|
should_record: d.InitVar[bool] = False
|
74
|
-
|
75
75
|
rich_kwargs: d.InitVar[dict[str, h.Any] | None] = None
|
76
76
|
|
77
|
+
@property
|
78
|
+
def past_logs_as_HTML(self) -> str | None:
|
79
|
+
""""""
|
80
|
+
console = self.console
|
81
|
+
if console.record:
|
82
|
+
return console.export_html()
|
83
|
+
|
84
|
+
return None
|
85
|
+
|
77
86
|
def __post_init__(
|
78
87
|
self,
|
79
88
|
name: str | None,
|
@@ -30,7 +30,7 @@ class file_handler_t(l.FileHandler):
|
|
30
30
|
should_store_memory_usage: d.InitVar[bool] = False
|
31
31
|
message_width: d.InitVar[int] = -1
|
32
32
|
formatter: d.InitVar[l.Formatter | None] = None
|
33
|
-
|
33
|
+
#
|
34
34
|
path: d.InitVar[path_t | None] = None
|
35
35
|
handler_args: d.InitVar[tuple[h.Any, ...] | None] = None
|
36
36
|
handler_kwargs: d.InitVar[dict[str, h.Any] | None] = None
|
@@ -66,7 +66,7 @@ class file_handler_t(l.FileHandler):
|
|
66
66
|
message = RuleAsText(record.msg)
|
67
67
|
else:
|
68
68
|
message = self.MessageFromRecord(record)
|
69
|
-
|
69
|
+
self.stream.write(message + "\n")
|
70
70
|
self.stream.flush()
|
71
71
|
|
72
72
|
def LogAsIs(self, message: str, /) -> None:
|
@@ -74,7 +74,7 @@ class file_handler_t(l.FileHandler):
|
|
74
74
|
See documentation of
|
75
75
|
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
76
76
|
"""
|
77
|
-
|
77
|
+
self.stream.write(message + "\n")
|
78
78
|
self.stream.flush()
|
79
79
|
|
80
80
|
def DisplayRule(self, /, *, text: str | None = None, color: str = "white") -> None:
|
@@ -75,7 +75,7 @@ class generic_handler_t(l.Handler):
|
|
75
75
|
should_store_memory_usage: d.InitVar[bool] = False
|
76
76
|
message_width: d.InitVar[int] = -1
|
77
77
|
formatter: d.InitVar[l.Formatter | None] = None
|
78
|
-
|
78
|
+
#
|
79
79
|
supports_html: d.InitVar[bool] = False
|
80
80
|
should_record: d.InitVar[bool] = False
|
81
81
|
rich_kwargs: d.InitVar[dict[str, h.Any] | None] = None
|
logger_36/catalog/logger/gpu.py
CHANGED
@@ -26,7 +26,7 @@ def LogGPURelatedDetails(*, logger: logger_t = L) -> None:
|
|
26
26
|
|
27
27
|
if None in (tsfl, tsrt):
|
28
28
|
if _GPU_LOGGING_ERROR is not None:
|
29
|
-
|
29
|
+
s.__stderr__.write(_GPU_LOGGING_ERROR + "\n")
|
30
30
|
_GPU_LOGGING_ERROR = None
|
31
31
|
return
|
32
32
|
|
logger_36/exception.py
CHANGED
@@ -76,14 +76,13 @@ def _HandleException(
|
|
76
76
|
|
77
77
|
document = tmpf.NamedTemporaryFile(delete=False)
|
78
78
|
|
79
|
-
|
79
|
+
s.__stderr__.write(
|
80
80
|
f"{stripe.__name__}\n"
|
81
81
|
f" {module}:{function}@{line_number}\n"
|
82
82
|
f"{line_content}"
|
83
83
|
f"{variables}"
|
84
84
|
f"{message}"
|
85
|
-
f" Full report at: {document.name}",
|
86
|
-
file=s.stderr,
|
85
|
+
f" Full report at: {document.name}\n",
|
87
86
|
)
|
88
87
|
|
89
88
|
lines = tcbk.format_exception(exception)
|
@@ -0,0 +1,107 @@
|
|
1
|
+
"""
|
2
|
+
Copyright CNRS/Inria/UniCA
|
3
|
+
Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
|
4
|
+
SEE COPYRIGHT NOTICE BELOW
|
5
|
+
"""
|
6
|
+
|
7
|
+
import dataclasses as d
|
8
|
+
import re as r
|
9
|
+
from html.parser import HTMLParser as base_t
|
10
|
+
|
11
|
+
_BODY_END_PATTERN = r"</[bB][oO][dD][yY]>(.|\n)*$"
|
12
|
+
|
13
|
+
|
14
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
15
|
+
class html_content_t(base_t):
|
16
|
+
source: str = ""
|
17
|
+
inside_body: bool = d.field(init=False, default=False)
|
18
|
+
body_position_start: tuple[int, int] = d.field(init=False, default=(-1, -1))
|
19
|
+
body_position_end: tuple[int, int] = d.field(init=False, default=(-1, -1))
|
20
|
+
pieces: list[str] = d.field(init=False, default_factory=list)
|
21
|
+
|
22
|
+
@property
|
23
|
+
def body(self) -> str:
|
24
|
+
""""""
|
25
|
+
output = self.source.splitlines()
|
26
|
+
output = "\n".join(
|
27
|
+
output[self.body_position_start[0] : (self.body_position_end[0] + 1)]
|
28
|
+
)
|
29
|
+
output = output[self.body_position_start[1] :]
|
30
|
+
output = r.sub(_BODY_END_PATTERN, "", output, count=1)
|
31
|
+
|
32
|
+
return output.strip()
|
33
|
+
|
34
|
+
@property
|
35
|
+
def body_as_text(self) -> str:
|
36
|
+
""""""
|
37
|
+
return "".join(self.pieces).strip()
|
38
|
+
|
39
|
+
def __post_init__(self) -> None:
|
40
|
+
""""""
|
41
|
+
base_t.__init__(self)
|
42
|
+
self.source = self.source.strip()
|
43
|
+
self.feed(self.source)
|
44
|
+
|
45
|
+
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]], /) -> None:
|
46
|
+
""""""
|
47
|
+
if tag == "body":
|
48
|
+
self.body_position_start = self.getpos()
|
49
|
+
self.inside_body = True
|
50
|
+
|
51
|
+
def handle_endtag(self, tag: str, /) -> None:
|
52
|
+
""""""
|
53
|
+
if tag == "body":
|
54
|
+
self.body_position_end = self.getpos()
|
55
|
+
self.inside_body = False
|
56
|
+
|
57
|
+
def handle_data(self, data: str, /) -> None:
|
58
|
+
""""""
|
59
|
+
if self.inside_body:
|
60
|
+
self.pieces.append(data)
|
61
|
+
|
62
|
+
|
63
|
+
"""
|
64
|
+
COPYRIGHT NOTICE
|
65
|
+
|
66
|
+
This software is governed by the CeCILL license under French law and
|
67
|
+
abiding by the rules of distribution of free software. You can use,
|
68
|
+
modify and/ or redistribute the software under the terms of the CeCILL
|
69
|
+
license as circulated by CEA, CNRS and INRIA at the following URL
|
70
|
+
"http://www.cecill.info".
|
71
|
+
|
72
|
+
As a counterpart to the access to the source code and rights to copy,
|
73
|
+
modify and redistribute granted by the license, users are provided only
|
74
|
+
with a limited warranty and the software's author, the holder of the
|
75
|
+
economic rights, and the successive licensors have only limited
|
76
|
+
liability.
|
77
|
+
|
78
|
+
In this respect, the user's attention is drawn to the risks associated
|
79
|
+
with loading, using, modifying and/or developing or reproducing the
|
80
|
+
software by the user in light of its specific status of free software,
|
81
|
+
that may mean that it is complicated to manipulate, and that also
|
82
|
+
therefore means that it is reserved for developers and experienced
|
83
|
+
professionals having in-depth computer knowledge. Users are therefore
|
84
|
+
encouraged to load and test the software's suitability as regards their
|
85
|
+
requirements in conditions enabling the security of their systems and/or
|
86
|
+
data to be ensured and, more generally, to use and operate it in the
|
87
|
+
same conditions as regards security.
|
88
|
+
|
89
|
+
The fact that you are presently reading this means that you have had
|
90
|
+
knowledge of the CeCILL license and that you accept its terms.
|
91
|
+
|
92
|
+
SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
|
93
|
+
|
94
|
+
This software is being developed by Eric Debreuve, a CNRS employee and
|
95
|
+
member of team Morpheme.
|
96
|
+
Team Morpheme is a joint team between Inria, CNRS, and UniCA.
|
97
|
+
It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
|
98
|
+
I3S, and Laboratory iBV.
|
99
|
+
|
100
|
+
CNRS: https://www.cnrs.fr/index.php/en
|
101
|
+
Inria: https://www.inria.fr/en/
|
102
|
+
UniCA: https://univ-cotedazur.eu/
|
103
|
+
Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
|
104
|
+
I3S: https://www.i3s.unice.fr/en/
|
105
|
+
iBV: http://ibv.unice.fr/
|
106
|
+
Team Morpheme: https://team.inria.fr/morpheme/
|
107
|
+
"""
|
logger_36/handler.py
CHANGED
@@ -94,7 +94,7 @@ def AddRichConsoleHandler(
|
|
94
94
|
""""""
|
95
95
|
global _MISSING_RICH_MESSAGE
|
96
96
|
if _MISSING_RICH_MESSAGE is not None:
|
97
|
-
|
97
|
+
s.__stderr__.write(_MISSING_RICH_MESSAGE + "\n")
|
98
98
|
_MISSING_RICH_MESSAGE = None
|
99
99
|
|
100
100
|
if console_rich_handler_t is console_handler_t:
|
logger_36/task/storage.py
CHANGED
@@ -4,73 +4,12 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
5
5
|
"""
|
6
6
|
|
7
|
-
import dataclasses as d
|
8
7
|
import logging as l
|
9
|
-
import re as r
|
10
|
-
from html.parser import HTMLParser as html_parser_t
|
11
8
|
from io import IOBase as io_base_t
|
12
9
|
from pathlib import Path as path_t
|
13
10
|
|
14
|
-
from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
|
15
11
|
from logger_36.instance.logger import L
|
16
12
|
|
17
|
-
if RICH_IS_AVAILABLE:
|
18
|
-
from rich.console import Console as console_t # noqa
|
19
|
-
else:
|
20
|
-
console_t = None
|
21
|
-
|
22
|
-
|
23
|
-
_BODY_END_PATTERN = r"</[bB][oO][dD][yY]>(.|\n)*$"
|
24
|
-
|
25
|
-
|
26
|
-
@d.dataclass(slots=True, repr=False, eq=False)
|
27
|
-
class html_reader_t(html_parser_t):
|
28
|
-
source: str = ""
|
29
|
-
inside_body: bool = d.field(init=False, default=False)
|
30
|
-
body_position_start: tuple[int, int] = d.field(init=False, default=(-1, -1))
|
31
|
-
body_position_end: tuple[int, int] = d.field(init=False, default=(-1, -1))
|
32
|
-
pieces: list[str] = d.field(init=False, default_factory=list)
|
33
|
-
|
34
|
-
def __post_init__(self) -> None:
|
35
|
-
""""""
|
36
|
-
html_parser_t.__init__(self)
|
37
|
-
self.source = self.source.strip()
|
38
|
-
self.feed(self.source)
|
39
|
-
|
40
|
-
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]], /) -> None:
|
41
|
-
""""""
|
42
|
-
if tag == "body":
|
43
|
-
self.body_position_start = self.getpos()
|
44
|
-
self.inside_body = True
|
45
|
-
|
46
|
-
def handle_endtag(self, tag: str, /) -> None:
|
47
|
-
""""""
|
48
|
-
if tag == "body":
|
49
|
-
self.body_position_end = self.getpos()
|
50
|
-
self.inside_body = False
|
51
|
-
|
52
|
-
def handle_data(self, data: str, /) -> None:
|
53
|
-
""""""
|
54
|
-
if self.inside_body:
|
55
|
-
self.pieces.append(data)
|
56
|
-
|
57
|
-
@property
|
58
|
-
def body(self) -> str:
|
59
|
-
""""""
|
60
|
-
output = self.source.splitlines()
|
61
|
-
output = "\n".join(
|
62
|
-
output[self.body_position_start[0] : (self.body_position_end[0] + 1)]
|
63
|
-
)
|
64
|
-
output = output[self.body_position_start[1] :]
|
65
|
-
output = r.sub(_BODY_END_PATTERN, "", output, count=1)
|
66
|
-
|
67
|
-
return output.strip()
|
68
|
-
|
69
|
-
@property
|
70
|
-
def body_as_text(self) -> str:
|
71
|
-
""""""
|
72
|
-
return "".join(self.pieces).strip()
|
73
|
-
|
74
13
|
|
75
14
|
def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None:
|
76
15
|
"""
|
@@ -78,18 +17,15 @@ def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None:
|
|
78
17
|
"""
|
79
18
|
cannot_save = "Cannot save logging record as HTML"
|
80
19
|
|
81
|
-
if console_t is None:
|
82
|
-
L.warning(f"{cannot_save}: The Rich console cannot be imported.")
|
83
|
-
return
|
84
|
-
|
85
20
|
if path is None:
|
86
21
|
for handler in L.handlers:
|
87
22
|
if isinstance(handler, l.FileHandler):
|
88
23
|
path = path_t(handler.baseFilename).with_suffix(".htm")
|
89
24
|
break
|
90
|
-
|
25
|
+
else:
|
91
26
|
L.warning(f"{cannot_save}: No file handler to build a filename from.")
|
92
27
|
return
|
28
|
+
|
93
29
|
if path.exists():
|
94
30
|
L.warning(
|
95
31
|
f'{cannot_save}: Automatically generated path "{path}" already exists.'
|
@@ -103,18 +39,15 @@ def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None:
|
|
103
39
|
L.warning(f'{cannot_save}: File "{path}" already exists.')
|
104
40
|
return
|
105
41
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
html = console.export_html()
|
110
|
-
if actual_file:
|
111
|
-
with open(path, "w") as accessor:
|
112
|
-
accessor.write(html)
|
113
|
-
else:
|
114
|
-
path.write(html)
|
115
|
-
break
|
42
|
+
html = L.past_logs_as_HTML
|
43
|
+
if html is None:
|
44
|
+
L.warning(f"{cannot_save}: No handler could provide an HTML output.")
|
116
45
|
else:
|
117
|
-
|
46
|
+
if actual_file:
|
47
|
+
with open(path, "w") as accessor:
|
48
|
+
accessor.write(html)
|
49
|
+
else:
|
50
|
+
path.write(html)
|
118
51
|
|
119
52
|
|
120
53
|
"""
|
logger_36/type/handler.py
CHANGED
@@ -73,7 +73,7 @@ class handler_extension_t:
|
|
73
73
|
if self.should_store_memory_usage and not CanCheckMemoryUsage():
|
74
74
|
self.should_store_memory_usage = False
|
75
75
|
if _MEMORY_MEASURE_ERROR is not None:
|
76
|
-
|
76
|
+
s.__stderr__.write(_MEMORY_MEASURE_ERROR + "\n")
|
77
77
|
_MEMORY_MEASURE_ERROR = None
|
78
78
|
|
79
79
|
handler.setLevel(level)
|
logger_36/type/logger.py
CHANGED
@@ -63,11 +63,14 @@ class logger_t(base_t):
|
|
63
63
|
"""
|
64
64
|
intercepted_wrn_handle: When warning interception is on, this stores the original
|
65
65
|
"handle" method of the Python warning logger.
|
66
|
-
"""
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
should_activate_log_interceptions: Loggers instantiated after a logger_t logger will
|
68
|
+
be missed by an early call of ToggleLogInterceptions. Therefore, passing True for
|
69
|
+
activate_log_interceptions only sets should_activate_log_interceptions to True,
|
70
|
+
which is later checked in AddHandler to effectively call ToggleLogInterceptions if
|
71
|
+
should_hold_messages is False (which normally indicates that the handler about to be
|
72
|
+
added is the last one).
|
73
|
+
"""
|
71
74
|
|
72
75
|
# Must not be False until at least one handler has been added.
|
73
76
|
should_hold_messages: bool = True
|
@@ -86,6 +89,12 @@ class logger_t(base_t):
|
|
86
89
|
intercepted_log_handles: dict[str, logger_handle_h] = d.field(
|
87
90
|
init=False, default_factory=dict
|
88
91
|
)
|
92
|
+
should_activate_log_interceptions: bool = False
|
93
|
+
|
94
|
+
name_: d.InitVar[str] = LOGGER_NAME
|
95
|
+
level_: d.InitVar[int] = l.NOTSET
|
96
|
+
activate_wrn_interceptions: d.InitVar[bool] = True
|
97
|
+
activate_log_interceptions: d.InitVar[bool] = True
|
89
98
|
|
90
99
|
@property
|
91
100
|
def intercepts_warnings(self) -> bool:
|
@@ -102,6 +111,18 @@ class logger_t(base_t):
|
|
102
111
|
""""""
|
103
112
|
return self.staged_issues.__len__() > 0
|
104
113
|
|
114
|
+
@property
|
115
|
+
def past_logs_as_HTML(self) -> str | None:
|
116
|
+
"""
|
117
|
+
From the first handler found with the given functionality, if any.
|
118
|
+
"""
|
119
|
+
for handler in self.handlers:
|
120
|
+
past_logs_as_HTML = getattr(handler, "past_logs_as_HTML", None)
|
121
|
+
if past_logs_as_HTML is not None:
|
122
|
+
return past_logs_as_HTML
|
123
|
+
|
124
|
+
return None
|
125
|
+
|
105
126
|
@property
|
106
127
|
def max_memory_usage(self) -> int:
|
107
128
|
""""""
|
@@ -121,7 +142,11 @@ class logger_t(base_t):
|
|
121
142
|
return "?", UNKNOWN_MEMORY_USAGE
|
122
143
|
|
123
144
|
def __post_init__(
|
124
|
-
self,
|
145
|
+
self,
|
146
|
+
name_: str,
|
147
|
+
level_: int,
|
148
|
+
activate_wrn_interceptions: bool,
|
149
|
+
activate_log_interceptions: bool,
|
125
150
|
) -> None:
|
126
151
|
""""""
|
127
152
|
base_t.__init__(self, name_)
|
@@ -135,6 +160,9 @@ class logger_t(base_t):
|
|
135
160
|
|
136
161
|
if activate_wrn_interceptions:
|
137
162
|
self.ToggleWarningInterceptions(True)
|
163
|
+
if activate_log_interceptions:
|
164
|
+
self.should_activate_log_interceptions = True
|
165
|
+
|
138
166
|
if self.exit_on_error:
|
139
167
|
self.exit_on_critical = True
|
140
168
|
|
@@ -250,72 +278,31 @@ class logger_t(base_t):
|
|
250
278
|
)
|
251
279
|
)
|
252
280
|
|
253
|
-
def MakeMonochrome(
|
254
|
-
self,
|
255
|
-
*,
|
256
|
-
should_intercept_logs: bool = True,
|
257
|
-
should_override_exceptions: bool = True,
|
258
|
-
) -> None:
|
281
|
+
def MakeMonochrome(self) -> None:
|
259
282
|
""""""
|
260
|
-
|
261
|
-
should_intercept_logs=should_intercept_logs,
|
262
|
-
should_override_exceptions=should_override_exceptions,
|
263
|
-
)
|
283
|
+
OverrideExceptionFormat()
|
264
284
|
AddConsoleHandler(self)
|
265
285
|
|
266
|
-
def MakeRich(
|
267
|
-
self,
|
268
|
-
*,
|
269
|
-
alternating_lines: int = 2,
|
270
|
-
should_intercept_logs: bool = True,
|
271
|
-
should_override_exceptions: bool = True,
|
272
|
-
) -> None:
|
286
|
+
def MakeRich(self, *, alternating_lines: int = 2) -> None:
|
273
287
|
""""""
|
274
|
-
|
275
|
-
should_intercept_logs=should_intercept_logs,
|
276
|
-
should_override_exceptions=should_override_exceptions,
|
277
|
-
)
|
288
|
+
OverrideExceptionFormat()
|
278
289
|
AddRichConsoleHandler(self, alternating_lines=alternating_lines)
|
279
290
|
|
280
|
-
def MakePermanent(
|
281
|
-
self,
|
282
|
-
path: str | path_t,
|
283
|
-
/,
|
284
|
-
*,
|
285
|
-
should_intercept_logs: bool = True,
|
286
|
-
should_override_exceptions: bool = True,
|
287
|
-
) -> None:
|
291
|
+
def MakePermanent(self, path: str | path_t, /) -> None:
|
288
292
|
""""""
|
289
|
-
|
290
|
-
should_intercept_logs=should_intercept_logs,
|
291
|
-
should_override_exceptions=should_override_exceptions,
|
292
|
-
)
|
293
|
+
OverrideExceptionFormat()
|
293
294
|
AddFileHandler(self, path)
|
294
295
|
|
295
|
-
def _MakePreamble(
|
296
|
-
self,
|
297
|
-
*,
|
298
|
-
should_intercept_logs: bool = True,
|
299
|
-
should_override_exceptions: bool = True,
|
300
|
-
) -> None:
|
301
|
-
""""""
|
302
|
-
if should_override_exceptions:
|
303
|
-
OverrideExceptionFormat()
|
304
|
-
if should_intercept_logs:
|
305
|
-
self.ToggleLogInterceptions(True)
|
306
|
-
|
307
296
|
def ResetEventCounts(self) -> None:
|
308
297
|
""""""
|
309
298
|
for level in self.events:
|
310
299
|
self.events[level] = 0
|
311
300
|
|
312
301
|
def ToggleWarningInterceptions(self, state: bool, /) -> None:
|
313
|
-
"""
|
314
|
-
The log message will not appear if called from __post_init__ since there are no
|
315
|
-
handlers yet.
|
316
|
-
"""
|
302
|
+
""""""
|
317
303
|
if state:
|
318
|
-
|
304
|
+
if self.intercepts_warnings:
|
305
|
+
return
|
319
306
|
|
320
307
|
logger = l.getLogger(WARNING_LOGGER_NAME)
|
321
308
|
self.intercepted_wrn_handle = logger.handle
|
@@ -324,7 +311,8 @@ class logger_t(base_t):
|
|
324
311
|
l.captureWarnings(True)
|
325
312
|
self.info("Warning Interception: ON")
|
326
313
|
else:
|
327
|
-
|
314
|
+
if not self.intercepts_warnings:
|
315
|
+
return
|
328
316
|
|
329
317
|
logger = l.getLogger(WARNING_LOGGER_NAME)
|
330
318
|
logger.handle = self.intercepted_wrn_handle
|
@@ -336,11 +324,14 @@ class logger_t(base_t):
|
|
336
324
|
def ToggleLogInterceptions(self, state: bool, /) -> None:
|
337
325
|
""""""
|
338
326
|
if state:
|
339
|
-
|
327
|
+
if self.intercepts_logs:
|
328
|
+
return
|
340
329
|
|
330
|
+
# Note: Alternative to self.manager is logging.root.manager.
|
331
|
+
all_loggers_names_but_root = self.manager.loggerDict.keys()
|
341
332
|
all_loggers = [l.getLogger()] + [
|
342
333
|
l.getLogger(_nme)
|
343
|
-
for _nme in
|
334
|
+
for _nme in all_loggers_names_but_root
|
344
335
|
if _nme not in (self.name, WARNING_LOGGER_NAME)
|
345
336
|
]
|
346
337
|
for logger in all_loggers:
|
@@ -354,7 +345,8 @@ class logger_t(base_t):
|
|
354
345
|
as_str = ", ".join(intercepted)
|
355
346
|
self.info(f"Now Intercepting LOGs from: {as_str}")
|
356
347
|
else:
|
357
|
-
|
348
|
+
if not self.intercepts_logs:
|
349
|
+
return
|
358
350
|
|
359
351
|
for name, handle in self.intercepted_log_handles.items():
|
360
352
|
logger = l.getLogger(name)
|
@@ -366,6 +358,10 @@ class logger_t(base_t):
|
|
366
358
|
self, handler: l.Handler, /, *, should_hold_messages: bool = False
|
367
359
|
) -> None:
|
368
360
|
""""""
|
361
|
+
if (not should_hold_messages) and self.should_activate_log_interceptions:
|
362
|
+
self.ToggleLogInterceptions(True)
|
363
|
+
self.should_activate_log_interceptions = False
|
364
|
+
|
369
365
|
self.should_hold_messages = should_hold_messages
|
370
366
|
base_t.addHandler(self, handler)
|
371
367
|
|
@@ -583,13 +579,18 @@ def _HandleForWarnings(interceptor: base_t, /) -> logger_handle_h:
|
|
583
579
|
path = GetPiece(1)
|
584
580
|
line = GetPiece(2)
|
585
581
|
kind = GetPiece(3)
|
586
|
-
message = GetPiece(4)
|
582
|
+
message = GetPiece(4)
|
583
|
+
|
584
|
+
path_as_t = path_t(path)
|
585
|
+
line = int(line)
|
586
|
+
line_content = path_as_t.read_text().splitlines()[line - 1]
|
587
|
+
message = message.replace(line_content.strip(), "").strip()
|
587
588
|
|
588
589
|
duplicate = l.makeLogRecord(record.__dict__)
|
589
590
|
duplicate.msg = f"{kind}: {message}"
|
590
591
|
duplicate.pathname = path
|
591
|
-
duplicate.module =
|
592
|
-
duplicate.funcName = "
|
592
|
+
duplicate.module = path_as_t.stem
|
593
|
+
duplicate.funcName = "<function>"
|
593
594
|
duplicate.lineno = line
|
594
595
|
|
595
596
|
interceptor.handle(duplicate)
|
logger_36/version.py
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
logger_36/__init__.py,sha256=3BtAgxFb14e9zzC5fXwqSQxstsd3BO0b_KVu3_wbLwg,2592
|
2
2
|
logger_36/content.py,sha256=clHYYUKa8n4qef6PVlUV4mFHRRf6fnm9wEd2fu9oagA,2381
|
3
|
-
logger_36/exception.py,sha256=
|
3
|
+
logger_36/exception.py,sha256=9YWnS2LN_Mc0qYkohtbgEkzKe9ja2h_dBEd39ytGbRU,4605
|
4
4
|
logger_36/gpu.py,sha256=BOumedCAPWvCo7J-KJ3XE-jr5S0KSmgcFv_S4QKRPO8,2252
|
5
|
-
logger_36/handler.py,sha256=
|
5
|
+
logger_36/handler.py,sha256=YOSkwLOO02Y69z-Hd7gtjng7s3VtgvlqnLMgv8jovI4,6309
|
6
6
|
logger_36/memory.py,sha256=szJVk4UTXsbYv3B-W9LFttf1F3j86GXHsKgEUOsXKl4,2743
|
7
7
|
logger_36/storage.py,sha256=sCxkHQH4xMaseweK1p2M1j0j2PxNPpy9MytPdg1sKiQ,2239
|
8
8
|
logger_36/system.py,sha256=cgOMF_OneYeIJDMbIbIDx96EZss2uAdkk8QofOC7O1U,2251
|
9
9
|
logger_36/time.py,sha256=Uw1jQtY1njsRuIPRAXX44v4nPOo84MSBu_WK_YCRzQs,2324
|
10
|
-
logger_36/version.py,sha256=
|
10
|
+
logger_36/version.py,sha256=GMhKYpDckX_jLa0A1mt1reiX5XWPRZxrdkZSXbm_Km4,2205
|
11
11
|
logger_36/api/logger.py,sha256=TE3ATbymeWX-wBKBFkVz2FxUyJnaqY7vzFwAONVsp2o,2233
|
12
|
-
logger_36/api/storage.py,sha256=
|
12
|
+
logger_36/api/storage.py,sha256=v1iywLEItJCz18F_nJ20OnlpCpLdA-7EhlvqdLu42js,2243
|
13
13
|
logger_36/catalog/config/console_rich.py,sha256=lAa5Ev5BhXvmQzfIt1FNihMNUQJFlXaIzNanAMdgtd0,2861
|
14
14
|
logger_36/catalog/config/optional.py,sha256=HaN6mbx7gHBBppNvUw1ckhYTOrlYqb-b_r0mzPcHPjM,2398
|
15
|
-
logger_36/catalog/handler/console.py,sha256=
|
16
|
-
logger_36/catalog/handler/console_rich.py,sha256=
|
17
|
-
logger_36/catalog/handler/file.py,sha256=
|
18
|
-
logger_36/catalog/handler/generic.py,sha256=
|
15
|
+
logger_36/catalog/handler/console.py,sha256=13ygxLmsywdGlr9hV9guw7FuRD-dxlZX20d1Mn-pWKs,4206
|
16
|
+
logger_36/catalog/handler/console_rich.py,sha256=E9ysE_aREozf9qz-ooxzVMwT3aj13U6Mb8qtmomYwSI,8549
|
17
|
+
logger_36/catalog/handler/file.py,sha256=ZbYLic0XcX3vw-col8hiuO-SQOSZh06tPYu5z3FdGDo,4620
|
18
|
+
logger_36/catalog/handler/generic.py,sha256=sJwqUFKEcziVAtHrPLDemEdeB1VU-F2gXkbbLtsYJ-g,9217
|
19
19
|
logger_36/catalog/logger/chronos.py,sha256=ocY13f98EfknU7wZCv0FS9Xb7pTNaWCPSusXFIEvEd4,2437
|
20
|
-
logger_36/catalog/logger/gpu.py,sha256=
|
20
|
+
logger_36/catalog/logger/gpu.py,sha256=n_kbAQdRNk3Jdket6031_r2unOcz3dWplhCR-WFPjE0,3417
|
21
21
|
logger_36/catalog/logger/memory.py,sha256=CWhr2J4BqArJxzH6tS-ZThr-rYPAQGtuLn0pP7Iryfg,4685
|
22
22
|
logger_36/catalog/logger/system.py,sha256=KXP2jdPd-ACFNdA0wWdmOLwuxt4baUvXkuChyOHyfy0,3066
|
23
23
|
logger_36/config/issue.py,sha256=G-i5p6lhZCLAOa-VTMyL9ZonvGCvhdoQ5KZdSWgP-FU,2267
|
@@ -34,20 +34,21 @@ logger_36/constant/message.py,sha256=Ys_CAyhENlT8Z3rr-AxO4hjdl1jLsKzVSPQ8wqLOCPQ
|
|
34
34
|
logger_36/constant/path.py,sha256=fKJn2vGj012BU5DFRetDFus_tKMty2q_WL0J2KrXdCo,2731
|
35
35
|
logger_36/constant/record.py,sha256=9Q28lVH_s0og4v74delgwIPAJ9G28I5rBM-brXcoY80,2308
|
36
36
|
logger_36/constant/system.py,sha256=G2mzBTxRXoJMxb53TnmBaceMJC_q3WonoCG7y6nC_R8,2430
|
37
|
+
logger_36/extension/html_.py,sha256=J9EX8-Rotq9i8bZ9U-dIpXv5gKLLnLmWqdDy4XayT1Q,3868
|
37
38
|
logger_36/instance/logger.py,sha256=oTw5svRzKRJKvGrrZUtutJIOjp5UISft3fl0Ze7DOBE,2241
|
38
39
|
logger_36/instance/loggers.py,sha256=RCWpC1NPAf6vXnFc9NqsSALv-x-FEzcH6k_OlxTxeQk,2251
|
39
40
|
logger_36/task/inspection.py,sha256=KZzmQyREQ6VmBWCLyNIYIOOISW9C_fC9TWTSX90zGDk,5019
|
40
|
-
logger_36/task/storage.py,sha256=
|
41
|
+
logger_36/task/storage.py,sha256=T96JZT5Tmrt_-Kqf_WKweTvJYPX6lmPZZkJzCqyVPcI,3502
|
41
42
|
logger_36/task/format/memory.py,sha256=jpQS8tAdxy7GM_FzqEIJUU3m-6O9iX-jiyO7gx5YwR8,4266
|
42
43
|
logger_36/task/format/message.py,sha256=T2V2gUlUQqSojyRrz4I4uAHwNe6eBEsuAe6V-LTyx0k,3867
|
43
44
|
logger_36/task/format/rule.py,sha256=vkf-HivFb4VqV2GeOPVqMAp99krtziI-kXhox3UVnzw,2873
|
44
45
|
logger_36/task/measure/chronos.py,sha256=1kVhu6jZlNAtNWQQh8ZVuRwZIAC9gGz3_ul1tn0t4Yw,3055
|
45
46
|
logger_36/task/measure/memory.py,sha256=OjU5EYFH8SnzlCQKAoiXvauUlwQYOrH34jFXTVYF0jE,2517
|
46
|
-
logger_36/type/handler.py,sha256
|
47
|
+
logger_36/type/handler.py,sha256=5g5KdmKk6cdsUSV0JoFfjpAXdQIzSRcW81STyLqqWq8,6824
|
47
48
|
logger_36/type/issue.py,sha256=2rGsFqaQJCbeml9xN08mN_nK79L8qscaS_0ws36Y0bI,3214
|
48
|
-
logger_36/type/logger.py,sha256=
|
49
|
+
logger_36/type/logger.py,sha256=4KkM_bIVRsjGO0ORloSibEb0MPtg88wSj5_wweRKjJU,22805
|
49
50
|
logger_36/type/loggers.py,sha256=znqxWBnfQxvkg3VUfbTUvt3S6Kq0DAzWWepxQDt9suI,2871
|
50
|
-
logger_36-2025.
|
51
|
-
logger_36-2025.
|
52
|
-
logger_36-2025.
|
53
|
-
logger_36-2025.
|
51
|
+
logger_36-2025.9.dist-info/METADATA,sha256=AMDXKjSSMDRqWDLT0FeNYlV9bWGc2s1LXSDTD_h93sg,6505
|
52
|
+
logger_36-2025.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
53
|
+
logger_36-2025.9.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
|
54
|
+
logger_36-2025.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|