logger-36 2024.20__py3-none-any.whl → 2024.22__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.
@@ -58,7 +58,10 @@ class console_handler_t(lggg.Handler):
58
58
  print(message)
59
59
 
60
60
  def ShowMessage(self, message: str, /) -> None:
61
- """"""
61
+ """
62
+ See documentation of
63
+ logger_36.catalog.handler.generic.generic_handler_t.ShowMessage.
64
+ """
62
65
  print(message)
63
66
 
64
67
 
@@ -155,7 +155,10 @@ class console_rich_handler_t(lggg.Handler):
155
155
  self.console.print(richer, crop=False, overflow="ignore")
156
156
 
157
157
  def ShowMessage(self, message: str, /) -> None:
158
- """"""
158
+ """
159
+ See documentation of
160
+ logger_36.catalog.handler.generic.generic_handler_t.ShowMessage.
161
+ """
159
162
  self.console.print(message, crop=False, overflow="ignore")
160
163
 
161
164
 
@@ -68,7 +68,10 @@ class file_handler_t(lggg.FileHandler):
68
68
  self.stream.flush()
69
69
 
70
70
  def ShowMessage(self, message: str, /) -> None:
71
- """"""
71
+ """
72
+ See documentation of
73
+ logger_36.catalog.handler.generic.generic_handler_t.ShowMessage.
74
+ """
72
75
  print(message, file=self.stream)
73
76
  self.stream.flush()
74
77
 
@@ -23,31 +23,35 @@ from logger_36.task.format.rule import Rule, RuleAsText
23
23
  from logger_36.type.handler import handler_extension_t
24
24
 
25
25
 
26
- class can_show_message_p(h.Protocol):
27
- def ShowMessage(self, message: str, /) -> None: ...
28
-
29
-
30
- interface_h = can_show_message_p | h.Callable[[str], None]
31
-
32
-
33
26
  @d.dataclass(slots=True, repr=False, eq=False)
34
27
  class generic_handler_t(lggg.Handler):
35
28
  """
36
29
  alternating_lines:
37
- - Initial value:
38
- - 1: enabled for dark background
39
- - 2: enabled for light background
40
- - anything else: disabled
41
- - Runtime value: 0/1=do not/do highlight next time.
30
+ - Initial value:
31
+ - 1: enabled for dark background
32
+ - 2: enabled for light background
33
+ - anything else: disabled
34
+ - Runtime value: 0/1=do not/do highlight next time.
35
+
36
+ ShowMessage:
37
+ Log a message as is, i.e. without formatting. If this is a method, it should
38
+ contain the same call(s) as the final ones in the emit methods that are used to
39
+ output the formatted log messages. This means that there is some code
40
+ duplication, but it avoids a (maybe negligible) slowing down that would arise
41
+ from calling this method at the end of the emit methods.
42
+ Here, since, by definition, the generic handler does not know how to output
43
+ messages, it is a callable attribute that must be set at instantiation time, and
44
+ it is indeed called at the end of the emit method.
42
45
  """
43
46
 
44
- extension: handler_extension_t = d.field(init=False)
47
+ ShowMessage: h.Callable[[str], None]
45
48
  console: console_t = None
46
49
  console_options: console_options_t = None
47
- FormattedLines: h.Callable[..., tuple[str, str | None]] = d.field(init=False)
48
50
  alternating_lines: int = 0
49
51
  background_is_light: bool = True
50
- ShowMessage: h.Callable[[str], None] = lambda _arg: None
52
+
53
+ extension: handler_extension_t = d.field(init=False)
54
+ FormattedLines: h.Callable[..., tuple[str, str | None]] = d.field(init=False)
51
55
 
52
56
  name: d.InitVar[str | None] = None
53
57
  level: d.InitVar[int] = lggg.NOTSET
@@ -59,7 +63,6 @@ class generic_handler_t(lggg.Handler):
59
63
  supports_html: d.InitVar[bool] = False
60
64
  should_record: d.InitVar[bool] = False
61
65
  rich_kwargs: d.InitVar[dict[str, h.Any] | None] = None
62
- interface: d.InitVar[interface_h | None] = None # Cannot be None actually.
63
66
 
64
67
  def __post_init__(
65
68
  self,
@@ -72,7 +75,6 @@ class generic_handler_t(lggg.Handler):
72
75
  supports_html: bool,
73
76
  should_record: bool,
74
77
  rich_kwargs: dict[str, h.Any] | None,
75
- interface: interface_h | None,
76
78
  ) -> None:
77
79
  """"""
78
80
  lggg.Handler.__init__(self)
@@ -110,10 +112,6 @@ class generic_handler_t(lggg.Handler):
110
112
  else:
111
113
  self.alternating_lines = -1
112
114
 
113
- self.ShowMessage = getattr(
114
- interface, can_show_message_p.ShowMessage.__name__, interface
115
- )
116
-
117
115
  def emit(self, record: lggg.LogRecord, /) -> None:
118
116
  """"""
119
117
  if self.console is None:
@@ -9,6 +9,8 @@ import typing as h
9
9
  order_h = h.Literal["when", "context"]
10
10
  ORDER: tuple[str, ...] = h.get_args(order_h)
11
11
 
12
+ ISSUE_LEVEL_SEPARATOR = "#"
13
+
12
14
  """
13
15
  COPYRIGHT NOTICE
14
16
 
logger_36/handler.py CHANGED
@@ -6,11 +6,12 @@ SEE COPYRIGHT NOTICE BELOW
6
6
 
7
7
  import logging as lggg
8
8
  import sys as sstm
9
+ import typing as h
9
10
  from pathlib import Path as path_t
10
11
 
11
12
  from logger_36.catalog.handler.console import console_handler_t
12
13
  from logger_36.catalog.handler.file import file_handler_t
13
- from logger_36.catalog.handler.generic import generic_handler_t, interface_h
14
+ from logger_36.catalog.handler.generic import generic_handler_t
14
15
  from logger_36.constant.error import MISSING_RICH_ERROR
15
16
  from logger_36.instance.logger import LOGGER
16
17
 
@@ -27,7 +28,7 @@ except ModuleNotFoundError:
27
28
 
28
29
 
29
30
  def AddGenericHandler(
30
- interface: interface_h,
31
+ ShowMessage: h.Callable[[str], None],
31
32
  /,
32
33
  *,
33
34
  logger: lggg.Logger | None = None,
@@ -58,7 +59,7 @@ def AddGenericHandler(
58
59
  alternating_lines=alternating_lines,
59
60
  should_record=should_record,
60
61
  rich_kwargs=kwargs,
61
- interface=interface,
62
+ ShowMessage=ShowMessage,
62
63
  )
63
64
  logger.AddHandler(handler, should_hold_messages)
64
65
 
logger_36/type/issue.py CHANGED
@@ -4,10 +4,12 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
4
4
  SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
+ import logging as lggg
7
8
  import typing as h
8
9
 
9
10
  from logger_36.config.issue import ISSUE_BASE_CONTEXT
10
11
  from logger_36.constant.generic import NOT_PASSED
12
+ from logger_36.constant.issue import ISSUE_LEVEL_SEPARATOR
11
13
  from logger_36.constant.message import expected_op_h
12
14
  from logger_36.task.format.message import FormattedMessage
13
15
 
@@ -20,6 +22,7 @@ def NewIssue(
20
22
  message: str,
21
23
  /,
22
24
  *,
25
+ level: int = lggg.ERROR,
23
26
  actual: h.Any = NOT_PASSED,
24
27
  expected: h.Any | None = None,
25
28
  expected_op: expected_op_h = "=",
@@ -36,7 +39,7 @@ def NewIssue(
36
39
  with_final_dot=with_final_dot,
37
40
  )
38
41
 
39
- return f"{context}{separator}{message}"
42
+ return f"{level}{ISSUE_LEVEL_SEPARATOR}{context}{separator}{message}"
40
43
 
41
44
 
42
45
  """
logger_36/type/logger.py CHANGED
@@ -17,7 +17,7 @@ from traceback import TracebackException as traceback_t
17
17
  from logger_36.config.issue import ISSUE_CONTEXT_END, ISSUE_CONTEXT_SEPARATOR
18
18
  from logger_36.config.message import DATE_FORMAT
19
19
  from logger_36.constant.generic import NOT_PASSED
20
- from logger_36.constant.issue import ORDER, order_h
20
+ from logger_36.constant.issue import ISSUE_LEVEL_SEPARATOR, ORDER, order_h
21
21
  from logger_36.constant.logger import (
22
22
  HIDE_WHERE_KWARG,
23
23
  LOGGER_NAME,
@@ -221,11 +221,12 @@ class logger_t(lggg.Logger):
221
221
  # __post_init__ set self.exit_on_critical if self.exit_on_error.
222
222
  sstm.exit(1)
223
223
 
224
- def error_for_exception(
224
+ def log_exception(
225
225
  self,
226
226
  exception: Exception,
227
227
  /,
228
228
  *,
229
+ level: int = lggg.ERROR,
229
230
  should_remove_caller: bool = False,
230
231
  ) -> None:
231
232
  """"""
@@ -233,9 +234,12 @@ class logger_t(lggg.Logger):
233
234
  if should_remove_caller:
234
235
  message = "\n".join(lines[:1] + lines[2:])
235
236
  else:
237
+ # TODO: Explain:
238
+ # - Why it's not: "\n".join(lines)?
239
+ # - Why adding excpetion name here and not when removing caller?
236
240
  formatted = "".join(lines)
237
241
  message = f"{type(exception).__name__}:\n{formatted}"
238
- self.error(message)
242
+ self.log(level, message)
239
243
 
240
244
  def AddContextLevel(self, new_level: str, /) -> None:
241
245
  """"""
@@ -255,6 +259,7 @@ class logger_t(lggg.Logger):
255
259
  message: str,
256
260
  /,
257
261
  *,
262
+ level: int = lggg.ERROR,
258
263
  actual: h.Any = NOT_PASSED,
259
264
  expected: h.Any | None = None,
260
265
  expected_op: expected_op_h = "=",
@@ -266,6 +271,7 @@ class logger_t(lggg.Logger):
266
271
  context,
267
272
  ISSUE_CONTEXT_END,
268
273
  message,
274
+ level=level,
269
275
  actual=actual,
270
276
  expected=expected,
271
277
  expected_op=expected_op,
@@ -280,12 +286,15 @@ class logger_t(lggg.Logger):
280
286
 
281
287
  def CommitIssues(
282
288
  self,
283
- level: int | type[Exception],
284
289
  /,
285
290
  *,
286
291
  order: order_h = "when",
292
+ unified: bool = False,
287
293
  ) -> None:
288
- """"""
294
+ """
295
+ Note that issues after an issue with a level triggering process exit will not be
296
+ logged.
297
+ """
289
298
  if not self.has_staged_issues:
290
299
  return
291
300
 
@@ -302,26 +311,35 @@ class logger_t(lggg.Logger):
302
311
  issues = self.staged_issues
303
312
  else: # order == "context"
304
313
  issues = sorted(self.staged_issues, key=lambda _elm: _elm.context)
305
- issues = "\n".join(issues)
306
-
307
- if isinstance(level, type) and issubclass(level, Exception):
308
- try:
309
- raise level("\n" + issues)
310
- except Exception as exception:
311
- lines = ["Traceback (most recent call last):"] + tcbk.format_stack()[
312
- :-1
313
- ]
314
- lines[-1] = lines[-1][:-1]
315
- lines.extend(tcbk.format_exception_only(exception))
316
- print("\n".join(lines), file=sstm.stderr)
317
- sstm.exit(1)
318
-
319
- level: int
320
- self.log(level, issues, stacklevel=2)
314
+ """
315
+ Format issues as an exception:
316
+ try:
317
+ raise ValueError("\n" + "\n".join(issues))
318
+ except ValueError as exception:
319
+ lines = ["Traceback (most recent call last):"] + tcbk.format_stack()[:-1]
320
+ lines[-1] = lines[-1][:-1]
321
+ lines.extend(tcbk.format_exception_only(exception))
322
+ formatted = "\n".join(lines)
323
+ """
324
+
325
+ if unified:
326
+ level, _ = issues[0].split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
327
+ wo_level = []
328
+ for issue in issues:
329
+ _, issue = issue.split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
330
+ wo_level.append(issue)
331
+ self.log(int(level), "\n".join(wo_level), stacklevel=2)
332
+ else:
333
+ for issue in issues:
334
+ level, issue = issue.split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
335
+ self.log(int(level), issue, stacklevel=2)
321
336
  self.staged_issues.clear()
322
337
 
323
338
  def ShowMessage(self, message: str, /) -> None:
324
- """"""
339
+ """
340
+ See documentation of
341
+ logger_36.catalog.handler.generic.generic_handler_t.ShowMessage.
342
+ """
325
343
  for handler in self.handlers:
326
344
  ShowMessage = getattr(handler, "ShowMessage", None)
327
345
  if ShowMessage is not None:
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__ = "2024.20"
7
+ __version__ = "2024.22"
8
8
 
9
9
  """
10
10
  COPYRIGHT NOTICE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: logger-36
3
- Version: 2024.20
3
+ Version: 2024.22
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,16 +1,16 @@
1
1
  logger_36/__init__.py,sha256=jHidpp6dmfJVdoiHkwTXBn1_u1HRaZj3BHS8jq71ZOE,2312
2
2
  logger_36/format.py,sha256=mox36RRkNUWbeHo3XkGGlik2CoyswDvDehRDtZkrnD0,2558
3
- logger_36/handler.py,sha256=wHMj4OyQrUdhAxk_MCvPTBT1Ig3BYpfbqxHYfp91fOU,6697
3
+ logger_36/handler.py,sha256=9KUu02RpKGKBR358gqS5G1Zut5C6MyBgGzRsQYFBAtY,6721
4
4
  logger_36/logger.py,sha256=7LJtdT7TmfFsn6r34iTr6OGvEjXlU6hKXEO2c5Lm2zY,2386
5
5
  logger_36/logger_gpu.py,sha256=YYFk6aYQrBDJfxQaDm-ar16T6SlOSL6jJWTOgvpF4EU,2244
6
6
  logger_36/measure.py,sha256=P507VNbVKAf4jYGnGX-3rlDrVbrYP0ZD3nxFmAFvhyI,2404
7
7
  logger_36/storage.py,sha256=O8pDmiL0B3LJpKrhi8a9IMBXs6MwW6r1bMUn_cSDAaY,2246
8
- logger_36/version.py,sha256=kB3U_JCF0IuEPCcFU8AehWEFC7kSh7E7ogHrmnWf-zY,2206
8
+ logger_36/version.py,sha256=JPQbndmeGc-ytruoejhakNRfDt3ogZPJwu9ZkQINvwA,2206
9
9
  logger_36/catalog/config/console_rich.py,sha256=QDkgSs3I7ZULvkd1q4J1hdvgyB857JJcJWxM9fdL51Y,2883
10
- logger_36/catalog/handler/console.py,sha256=1WLtmxZCBj0AxLu5xey3VIVBKm02bp-Rc-eZOiFtXnU,3893
11
- logger_36/catalog/handler/console_rich.py,sha256=v57EFAvCaH5ABoZ24lFn1ObCe_EntHpqzW7RJLs6Lik,8681
12
- logger_36/catalog/handler/file.py,sha256=GS5nsfp0j0mzPak7vz8E7U4e5H95os_qfDjdM1Ywf0g,4345
13
- logger_36/catalog/handler/generic.py,sha256=93hiUjp0EsmH9M-kUHLKiFmvwSWTzb4JeYH-4T-6aT4,8123
10
+ logger_36/catalog/handler/console.py,sha256=SF9S3CUoEPp5dh7RrqotywDJjMgRp0rD9sO3eLVXnkA,4004
11
+ logger_36/catalog/handler/console_rich.py,sha256=Ti1k2E1ox4egzicghTb9Wv30xiWaBbWwe8ouopJsujY,8792
12
+ logger_36/catalog/handler/file.py,sha256=z5ovaOxemh61pbWDCK2sMMlbd1TKwGjMiQhgoicilm4,4456
13
+ logger_36/catalog/handler/generic.py,sha256=wG6Z1-lHj_9o6cPurEVpPctFlec3BFeqx2mZU_krJt8,8379
14
14
  logger_36/catalog/logger/chronos.py,sha256=eLqQw8N9vaGO23OCf5RrYDPbUeu7epUvDt9rH-dN7i0,2522
15
15
  logger_36/catalog/logger/gpu.py,sha256=vUFSP17e7U4nenMi5IMlDiP3cZvXe6nqEDpoqzTavdg,3490
16
16
  logger_36/catalog/logger/memory.py,sha256=Zel_UCnHqGAqf_YuKpvjt0OIOo9vwKYpFM9g_2bjir0,4790
@@ -23,7 +23,7 @@ logger_36/config/system.py,sha256=HD8ZuwsXhEAExeZrww8YoDkQGMs4T5RDqQMb1W4qVgc,24
23
23
  logger_36/constant/error.py,sha256=1gdnCwUu3d3ThL4AKxzjn7ijSTBWlr2g-8cAKbubl4A,2825
24
24
  logger_36/constant/generic.py,sha256=t6aRb66_NHwMhR1p7BZ4QXTU2jpLz-H5YAL4PuMtKx8,2244
25
25
  logger_36/constant/handler.py,sha256=HM8qCSEMGNMCzddjUUNBPGL-3d0qU-EmG5eW4ZQHW6A,2311
26
- logger_36/constant/issue.py,sha256=48c3QGNzgRcvQOenlp77_wAU4znZfLkQEdT2oE_CvMs,2286
26
+ logger_36/constant/issue.py,sha256=01l8itRPWGS5F6gXtsXUJgGR-4lS1Eu3_YeKC-khKLw,2315
27
27
  logger_36/constant/logger.py,sha256=0GhemAQ_YBiRO5WQBuNTczuejyVu2IYCsgqPRIbL8es,2780
28
28
  logger_36/constant/memory.py,sha256=ZL1MwbdtNsrCrOwzEyfTsfOoOsRBTJtbbf3otHGnxXo,2343
29
29
  logger_36/constant/message.py,sha256=RKQL-YmEDds5q7HuHTeDebz7_h3zWDX0PNxu-RTwL2I,2714
@@ -39,10 +39,10 @@ logger_36/task/format/rule.py,sha256=YEe8wG_QLy9vRZqmT2bWlvKT-Dxp4pGaZVmEuwwODyE
39
39
  logger_36/task/measure/chronos.py,sha256=t-y0bVm1SmF-3wI9pR9Bp6-qzVlsE94fZTZr5a_hZUA,2884
40
40
  logger_36/task/measure/memory.py,sha256=eVw5WOYLyn8o4O4mMArdX2MzsVuhhNDovjYEkk-MIaU,2504
41
41
  logger_36/type/handler.py,sha256=BXpevZhLq5V_IdUfi_LZA4czzlH2SGLpgvbqUBe5X10,8311
42
- logger_36/type/issue.py,sha256=cB8pSSJg9aqFPQ6yJr4TC2kJbngKGK8Hyq4ATBm6jAc,2973
43
- logger_36/type/logger.py,sha256=qC2ThKusY4RKcmxxWaO2Pg3TTStUxpVe4AcSuQBdU04,15123
42
+ logger_36/type/issue.py,sha256=5NCcDX8uTcp4Zd7HoRTYB2_f3RVjqHeDEavkssr6bg0,3114
43
+ logger_36/type/logger.py,sha256=sH-eEEt3_kdYSTS4C3sLXA_pp-2MH-D_Bf6EDlJNY1E,15935
44
44
  logger_36/type/loggers.py,sha256=znqxWBnfQxvkg3VUfbTUvt3S6Kq0DAzWWepxQDt9suI,2871
45
- logger_36-2024.20.dist-info/METADATA,sha256=iyBqlOa3h_y5wyAOCzS8uLDNMgJo1DrFb88cOaPNm6Q,6276
46
- logger_36-2024.20.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
47
- logger_36-2024.20.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
48
- logger_36-2024.20.dist-info/RECORD,,
45
+ logger_36-2024.22.dist-info/METADATA,sha256=K5YZ0rA-ldUEqGnM3lMh09FzH9fmEY7gTZC7eWyTpcE,6276
46
+ logger_36-2024.22.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
47
+ logger_36-2024.22.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
48
+ logger_36-2024.22.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (74.1.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5