logger-36 2025.8__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.
@@ -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
- print(message)
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
- print(message)
69
+ s.__stdout__.write(message + "\n")
69
70
 
70
71
  def DisplayRule(self, /, *, text: str | None = None, color: str = "white") -> None:
71
72
  """"""
@@ -69,9 +69,9 @@ 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
77
  @property
@@ -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
- print(message, file=self.stream)
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
- print(message, file=self.stream)
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
@@ -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
- print(_GPU_LOGGING_ERROR, file=s.stderr)
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
- print(
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)
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
- print(_MISSING_RICH_MESSAGE, file=s.stderr)
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/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
- print(_MEMORY_MEASURE_ERROR, file=s.stderr)
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
- name_: d.InitVar[str] = LOGGER_NAME
69
- level_: d.InitVar[int] = l.NOTSET
70
- activate_wrn_interceptions: d.InitVar[bool] = True
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:
@@ -133,7 +142,11 @@ class logger_t(base_t):
133
142
  return "?", UNKNOWN_MEMORY_USAGE
134
143
 
135
144
  def __post_init__(
136
- self, name_: str, level_: int, activate_wrn_interceptions: bool
145
+ self,
146
+ name_: str,
147
+ level_: int,
148
+ activate_wrn_interceptions: bool,
149
+ activate_log_interceptions: bool,
137
150
  ) -> None:
138
151
  """"""
139
152
  base_t.__init__(self, name_)
@@ -147,6 +160,9 @@ class logger_t(base_t):
147
160
 
148
161
  if activate_wrn_interceptions:
149
162
  self.ToggleWarningInterceptions(True)
163
+ if activate_log_interceptions:
164
+ self.should_activate_log_interceptions = True
165
+
150
166
  if self.exit_on_error:
151
167
  self.exit_on_critical = True
152
168
 
@@ -262,72 +278,31 @@ class logger_t(base_t):
262
278
  )
263
279
  )
264
280
 
265
- def MakeMonochrome(
266
- self,
267
- *,
268
- should_intercept_logs: bool = True,
269
- should_override_exceptions: bool = True,
270
- ) -> None:
281
+ def MakeMonochrome(self) -> None:
271
282
  """"""
272
- self._MakePreamble(
273
- should_intercept_logs=should_intercept_logs,
274
- should_override_exceptions=should_override_exceptions,
275
- )
283
+ OverrideExceptionFormat()
276
284
  AddConsoleHandler(self)
277
285
 
278
- def MakeRich(
279
- self,
280
- *,
281
- alternating_lines: int = 2,
282
- should_intercept_logs: bool = True,
283
- should_override_exceptions: bool = True,
284
- ) -> None:
286
+ def MakeRich(self, *, alternating_lines: int = 2) -> None:
285
287
  """"""
286
- self._MakePreamble(
287
- should_intercept_logs=should_intercept_logs,
288
- should_override_exceptions=should_override_exceptions,
289
- )
288
+ OverrideExceptionFormat()
290
289
  AddRichConsoleHandler(self, alternating_lines=alternating_lines)
291
290
 
292
- def MakePermanent(
293
- self,
294
- path: str | path_t,
295
- /,
296
- *,
297
- should_intercept_logs: bool = True,
298
- should_override_exceptions: bool = True,
299
- ) -> None:
291
+ def MakePermanent(self, path: str | path_t, /) -> None:
300
292
  """"""
301
- self._MakePreamble(
302
- should_intercept_logs=should_intercept_logs,
303
- should_override_exceptions=should_override_exceptions,
304
- )
293
+ OverrideExceptionFormat()
305
294
  AddFileHandler(self, path)
306
295
 
307
- def _MakePreamble(
308
- self,
309
- *,
310
- should_intercept_logs: bool = True,
311
- should_override_exceptions: bool = True,
312
- ) -> None:
313
- """"""
314
- if should_override_exceptions:
315
- OverrideExceptionFormat()
316
- if should_intercept_logs:
317
- self.ToggleLogInterceptions(True)
318
-
319
296
  def ResetEventCounts(self) -> None:
320
297
  """"""
321
298
  for level in self.events:
322
299
  self.events[level] = 0
323
300
 
324
301
  def ToggleWarningInterceptions(self, state: bool, /) -> None:
325
- """
326
- The log message will not appear if called from __post_init__ since there are no
327
- handlers yet.
328
- """
302
+ """"""
329
303
  if state:
330
- assert not self.intercepts_warnings
304
+ if self.intercepts_warnings:
305
+ return
331
306
 
332
307
  logger = l.getLogger(WARNING_LOGGER_NAME)
333
308
  self.intercepted_wrn_handle = logger.handle
@@ -336,7 +311,8 @@ class logger_t(base_t):
336
311
  l.captureWarnings(True)
337
312
  self.info("Warning Interception: ON")
338
313
  else:
339
- assert self.intercepts_warnings
314
+ if not self.intercepts_warnings:
315
+ return
340
316
 
341
317
  logger = l.getLogger(WARNING_LOGGER_NAME)
342
318
  logger.handle = self.intercepted_wrn_handle
@@ -348,12 +324,14 @@ class logger_t(base_t):
348
324
  def ToggleLogInterceptions(self, state: bool, /) -> None:
349
325
  """"""
350
326
  if state:
351
- assert not self.intercepts_logs
327
+ if self.intercepts_logs:
328
+ return
352
329
 
353
330
  # Note: Alternative to self.manager is logging.root.manager.
331
+ all_loggers_names_but_root = self.manager.loggerDict.keys()
354
332
  all_loggers = [l.getLogger()] + [
355
333
  l.getLogger(_nme)
356
- for _nme in self.manager.loggerDict
334
+ for _nme in all_loggers_names_but_root
357
335
  if _nme not in (self.name, WARNING_LOGGER_NAME)
358
336
  ]
359
337
  for logger in all_loggers:
@@ -367,7 +345,8 @@ class logger_t(base_t):
367
345
  as_str = ", ".join(intercepted)
368
346
  self.info(f"Now Intercepting LOGs from: {as_str}")
369
347
  else:
370
- assert self.intercepts_logs
348
+ if not self.intercepts_logs:
349
+ return
371
350
 
372
351
  for name, handle in self.intercepted_log_handles.items():
373
352
  logger = l.getLogger(name)
@@ -379,6 +358,10 @@ class logger_t(base_t):
379
358
  self, handler: l.Handler, /, *, should_hold_messages: bool = False
380
359
  ) -> None:
381
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
+
382
365
  self.should_hold_messages = should_hold_messages
383
366
  base_t.addHandler(self, handler)
384
367
 
@@ -596,13 +579,18 @@ def _HandleForWarnings(interceptor: base_t, /) -> logger_handle_h:
596
579
  path = GetPiece(1)
597
580
  line = GetPiece(2)
598
581
  kind = GetPiece(3)
599
- message = GetPiece(4).strip()
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()
600
588
 
601
589
  duplicate = l.makeLogRecord(record.__dict__)
602
590
  duplicate.msg = f"{kind}: {message}"
603
591
  duplicate.pathname = path
604
- duplicate.module = path_t(path).stem
605
- duplicate.funcName = "?"
592
+ duplicate.module = path_as_t.stem
593
+ duplicate.funcName = "<function>"
606
594
  duplicate.lineno = line
607
595
 
608
596
  interceptor.handle(duplicate)
logger_36/version.py CHANGED
@@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
4
4
  SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
- __version__ = "2025.8"
7
+ __version__ = "2025.9"
8
8
 
9
9
  """
10
10
  COPYRIGHT NOTICE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: logger-36
3
- Version: 2025.8
3
+ Version: 2025.9
4
4
  Summary: Simple logger with a catalog of handlers
5
5
  Home-page: https://src.koda.cnrs.fr/eric.debreuve/logger-36/
6
6
  Author: Eric Debreuve
@@ -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=BQm9maX9CMjpqN26cEsArPCcX37LqYtQSrUZ3fN8tbU,4613
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=pIwunW-_aSB-SrdlvVmq61nOTH03deKIVcJa4Sz_hkc,6304
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=dIKiLoaPWfEeTZKKzEklIyLlE8cFbHUq2h72W5GmOiI,2205
10
+ logger_36/version.py,sha256=GMhKYpDckX_jLa0A1mt1reiX5XWPRZxrdkZSXbm_Km4,2205
11
11
  logger_36/api/logger.py,sha256=TE3ATbymeWX-wBKBFkVz2FxUyJnaqY7vzFwAONVsp2o,2233
12
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=s2DBcDK9To-wVS228RsDDPmOPxlIbVnQbZINfIK2TP0,4150
16
- logger_36/catalog/handler/console_rich.py,sha256=uYCoxPBPypaioSibC68Vw9r1XoY8AB5pAq2-RV1a4wQ,8544
17
- logger_36/catalog/handler/file.py,sha256=2qbsI3UHxqEm9WiCMkAm20hA2qXth2wKnakazVbwrBs,4613
18
- logger_36/catalog/handler/generic.py,sha256=y-f6HY5xppoHYYnej0qOQT3BI0Gam_0W1_bIHCk5nn0,9212
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=lzrkqrMnXsszRB_TiHFqnNNI7JhNat8qL2OSlnHDe5c,3412
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
@@ -44,11 +44,11 @@ logger_36/task/format/message.py,sha256=T2V2gUlUQqSojyRrz4I4uAHwNe6eBEsuAe6V-LTy
44
44
  logger_36/task/format/rule.py,sha256=vkf-HivFb4VqV2GeOPVqMAp99krtziI-kXhox3UVnzw,2873
45
45
  logger_36/task/measure/chronos.py,sha256=1kVhu6jZlNAtNWQQh8ZVuRwZIAC9gGz3_ul1tn0t4Yw,3055
46
46
  logger_36/task/measure/memory.py,sha256=OjU5EYFH8SnzlCQKAoiXvauUlwQYOrH34jFXTVYF0jE,2517
47
- logger_36/type/handler.py,sha256=-myl7uBMOzkwCs1u4ehuYlQa9F6909jmnL2v_eQN5ag,6819
47
+ logger_36/type/handler.py,sha256=5g5KdmKk6cdsUSV0JoFfjpAXdQIzSRcW81STyLqqWq8,6824
48
48
  logger_36/type/issue.py,sha256=2rGsFqaQJCbeml9xN08mN_nK79L8qscaS_0ws36Y0bI,3214
49
- logger_36/type/logger.py,sha256=J6J87-RkH0RwiROeDQBnoTxLO5eXz32-GKjtxqyRXwk,22743
49
+ logger_36/type/logger.py,sha256=4KkM_bIVRsjGO0ORloSibEb0MPtg88wSj5_wweRKjJU,22805
50
50
  logger_36/type/loggers.py,sha256=znqxWBnfQxvkg3VUfbTUvt3S6Kq0DAzWWepxQDt9suI,2871
51
- logger_36-2025.8.dist-info/METADATA,sha256=R6yfIOmsKd4dJgf9EwdP7Mv1TtSlLD04g5liwcKXPOU,6505
52
- logger_36-2025.8.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
53
- logger_36-2025.8.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
54
- logger_36-2025.8.dist-info/RECORD,,
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,,