logger-36 2025.12__tar.gz → 2025.14__tar.gz

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.
Files changed (70) hide show
  1. {logger_36-2025.12 → logger_36-2025.14}/PKG-INFO +2 -2
  2. logger_36-2025.14/package/logger_36/catalog/handler/console.py +93 -0
  3. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/handler/console_rich.py +73 -87
  4. logger_36-2025.14/package/logger_36/catalog/handler/file.py +98 -0
  5. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/handler/generic.py +67 -68
  6. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/logger/gpu.py +1 -1
  7. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/logger/system.py +1 -1
  8. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/config/message.py +1 -0
  9. logger_36-2025.14/package/logger_36/constant/html.py +70 -0
  10. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/extension/exception.py +4 -2
  11. logger_36-2025.14/package/logger_36/extension/line.py +83 -0
  12. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/format/memory.py +1 -5
  13. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/format/message.py +60 -1
  14. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/format/rule.py +3 -2
  15. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/inspection.py +1 -1
  16. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/storage.py +29 -8
  17. logger_36-2025.14/package/logger_36/type/handler.py +195 -0
  18. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/type/logger.py +92 -60
  19. logger_36-2025.14/package/logger_36/type/message.py +90 -0
  20. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/version.py +1 -1
  21. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36.egg-info/PKG-INFO +2 -2
  22. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36.egg-info/SOURCES.txt +4 -3
  23. {logger_36-2025.12 → logger_36-2025.14}/setup.py +1 -4
  24. logger_36-2025.12/package/logger_36/api/handler.py +0 -58
  25. logger_36-2025.12/package/logger_36/catalog/handler/console.py +0 -120
  26. logger_36-2025.12/package/logger_36/catalog/handler/file.py +0 -129
  27. logger_36-2025.12/package/logger_36/task/handling.py +0 -196
  28. logger_36-2025.12/package/logger_36/type/handler.py +0 -200
  29. {logger_36-2025.12 → logger_36-2025.14}/MANIFEST.in +0 -0
  30. {logger_36-2025.12 → logger_36-2025.14}/README-COPYRIGHT-utf8.txt +0 -0
  31. {logger_36-2025.12 → logger_36-2025.14}/README-LICENCE-utf8.txt +0 -0
  32. {logger_36-2025.12 → logger_36-2025.14}/README.rst +0 -0
  33. {logger_36-2025.12 → logger_36-2025.14}/documentation/wiki/description.asciidoc +0 -0
  34. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/__init__.py +0 -0
  35. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/content.py +0 -0
  36. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/exception.py +0 -0
  37. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/gpu.py +0 -0
  38. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/memory.py +0 -0
  39. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/storage.py +0 -0
  40. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/system.py +0 -0
  41. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/time.py +0 -0
  42. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/api/type.py +0 -0
  43. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/config/console_rich.py +0 -0
  44. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/config/optional.py +0 -0
  45. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/logger/chronos.py +0 -0
  46. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/catalog/logger/memory.py +0 -0
  47. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/config/issue.py +0 -0
  48. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/config/memory.py +0 -0
  49. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/config/system.py +0 -0
  50. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/error.py +0 -0
  51. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/generic.py +0 -0
  52. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/handler.py +0 -0
  53. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/issue.py +0 -0
  54. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/logger.py +0 -0
  55. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/memory.py +0 -0
  56. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/message.py +0 -0
  57. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/path.py +0 -0
  58. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/record.py +0 -0
  59. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/constant/system.py +0 -0
  60. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/extension/html_.py +0 -0
  61. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/instance/logger.py +0 -0
  62. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/instance/loggers.py +0 -0
  63. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/measure/chronos.py +0 -0
  64. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/task/measure/memory.py +0 -0
  65. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/type/issue.py +0 -0
  66. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36/type/loggers.py +0 -0
  67. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36.egg-info/dependency_links.txt +0 -0
  68. {logger_36-2025.12 → logger_36-2025.14}/package/logger_36.egg-info/top_level.txt +0 -0
  69. {logger_36-2025.12 → logger_36-2025.14}/pyproject.toml +0 -0
  70. {logger_36-2025.12 → logger_36-2025.14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: logger-36
3
- Version: 2025.12
3
+ Version: 2025.14
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
@@ -0,0 +1,93 @@
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 logging as l
8
+ import sys as s
9
+ import typing as h
10
+
11
+ from logger_36.task.format.rule import RuleAsText
12
+ from logger_36.type.handler import handler_t as base_t
13
+
14
+
15
+ class console_handler_t(base_t):
16
+ kind: h.ClassVar[str] = "c"
17
+
18
+ @classmethod
19
+ def New(
20
+ cls,
21
+ /,
22
+ *,
23
+ name: str | None = None,
24
+ should_store_memory_usage: bool = False,
25
+ message_width: int = -1,
26
+ level: int = l.NOTSET,
27
+ formatter: l.Formatter | None = None,
28
+ **_,
29
+ ) -> h.Self:
30
+ """"""
31
+ return cls(name, should_store_memory_usage, message_width, level, formatter)
32
+
33
+ def emit(self, record: l.LogRecord, /) -> None:
34
+ """"""
35
+ message = self.MessageFromRecord(
36
+ record, RuleAsText, line_width=self.message_width
37
+ )
38
+ s.__stdout__.write(message[0] + "\n")
39
+
40
+ def LogAsIs(self, message: str, /) -> None:
41
+ """"""
42
+ s.__stdout__.write(message + "\n")
43
+
44
+ def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
45
+ """"""
46
+ self.LogAsIs(RuleAsText(text, None))
47
+
48
+
49
+ """
50
+ COPYRIGHT NOTICE
51
+
52
+ This software is governed by the CeCILL license under French law and
53
+ abiding by the rules of distribution of free software. You can use,
54
+ modify and/ or redistribute the software under the terms of the CeCILL
55
+ license as circulated by CEA, CNRS and INRIA at the following URL
56
+ "http://www.cecill.info".
57
+
58
+ As a counterpart to the access to the source code and rights to copy,
59
+ modify and redistribute granted by the license, users are provided only
60
+ with a limited warranty and the software's author, the holder of the
61
+ economic rights, and the successive licensors have only limited
62
+ liability.
63
+
64
+ In this respect, the user's attention is drawn to the risks associated
65
+ with loading, using, modifying and/or developing or reproducing the
66
+ software by the user in light of its specific status of free software,
67
+ that may mean that it is complicated to manipulate, and that also
68
+ therefore means that it is reserved for developers and experienced
69
+ professionals having in-depth computer knowledge. Users are therefore
70
+ encouraged to load and test the software's suitability as regards their
71
+ requirements in conditions enabling the security of their systems and/or
72
+ data to be ensured and, more generally, to use and operate it in the
73
+ same conditions as regards security.
74
+
75
+ The fact that you are presently reading this means that you have had
76
+ knowledge of the CeCILL license and that you accept its terms.
77
+
78
+ SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
79
+
80
+ This software is being developed by Eric Debreuve, a CNRS employee and
81
+ member of team Morpheme.
82
+ Team Morpheme is a joint team between Inria, CNRS, and UniCA.
83
+ It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
84
+ I3S, and Laboratory iBV.
85
+
86
+ CNRS: https://www.cnrs.fr/index.php/en
87
+ Inria: https://www.inria.fr/en/
88
+ UniCA: https://univ-cotedazur.eu/
89
+ Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
90
+ I3S: https://www.i3s.unice.fr/en/
91
+ iBV: http://ibv.unice.fr/
92
+ Team Morpheme: https://team.inria.fr/morpheme/
93
+ """
@@ -4,10 +4,15 @@ 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
8
  import typing as h
10
9
 
10
+ from rich.console import Console as console_t # noqa
11
+ from rich.console import RenderableType as renderable_t # noqa
12
+ from rich.markup import escape as EscapedVersion # noqa
13
+ from rich.text import Text as text_t # noqa
14
+ from rich.traceback import install as InstallTracebackHandler # noqa
15
+
11
16
  from logger_36.catalog.config.console_rich import (
12
17
  ACTUAL_COLOR,
13
18
  ALTERNATIVE_BACKGROUND_FOR_DARK,
@@ -20,14 +25,8 @@ from logger_36.catalog.config.console_rich import (
20
25
  )
21
26
  from logger_36.config.message import ACTUAL_PATTERNS, EXPECTED_PATTERNS, WHERE_SEPARATOR
22
27
  from logger_36.constant.message import CONTEXT_LENGTH
23
- from logger_36.constant.record import SHOW_W_RULE_ATTR
24
28
  from logger_36.task.format.rule import Rule
25
- from logger_36.type.handler import MessageFromRecordPreprocessed_p, handler_extension_t
26
- from rich.console import Console as console_t # noqa
27
- from rich.console import RenderableType as renderable_t # noqa
28
- from rich.markup import escape as EscapedVersion # noqa
29
- from rich.text import Text as text_t # noqa
30
- from rich.traceback import install as InstallTracebackHandler # noqa
29
+ from logger_36.type.handler import handler_t as base_t
31
30
 
32
31
  _COMMON_TRACEBACK_ARGUMENTS = ("theme", "width")
33
32
  _EXCLUSIVE_TRACEBACK_ARGUMENTS = (
@@ -37,17 +36,14 @@ _EXCLUSIVE_TRACEBACK_ARGUMENTS = (
37
36
  "locals_hide_sunder",
38
37
  "locals_max_length",
39
38
  "locals_max_string",
40
- "max_frames" "show_locals",
39
+ "max_framesshow_locals",
41
40
  "suppress",
42
41
  "word_wrap",
43
42
  )
44
43
 
45
44
 
46
- @d.dataclass(slots=True, repr=False, eq=False)
47
- class console_rich_handler_t(l.Handler):
45
+ class console_rich_handler_t(base_t):
48
46
  """
49
- kind: See logger_36.constant.handler.handler_codes_h.
50
-
51
47
  alternating_logs:
52
48
  - 0: disabled
53
49
  - 1: enabled for dark background
@@ -56,105 +52,95 @@ class console_rich_handler_t(l.Handler):
56
52
 
57
53
  kind: h.ClassVar[str] = "c"
58
54
 
59
- alternating_logs: int = 0
60
-
61
- name: d.InitVar[str | None] = None
62
- level: d.InitVar[int] = l.NOTSET
63
- should_store_memory_usage: d.InitVar[bool] = False
64
- message_width: d.InitVar[int] = -1
65
- formatter: d.InitVar[l.Formatter | None] = None
66
- #
67
- should_install_traceback: d.InitVar[bool] = False
68
- should_record: d.InitVar[bool] = False
69
- rich_kwargs: d.InitVar[dict[str, h.Any] | None] = None
70
-
71
- extension: handler_extension_t = d.field(init=False)
72
- console: console_t = d.field(init=False)
73
- MessageFromRecord: MessageFromRecordPreprocessed_p = d.field(init=False)
74
- log_parity: bool = d.field(init=False, default=False)
75
-
76
- @property
77
- def past_logs_as_HTML(self) -> str | None:
78
- """"""
79
- console = self.console
80
- if console.record:
81
- return console.export_html()
82
-
83
- return None
84
-
85
- def __post_init__(
55
+ def __init__(
86
56
  self,
87
57
  name: str | None,
88
- level: int,
89
58
  should_store_memory_usage: bool,
90
59
  message_width: int,
60
+ level: int,
91
61
  formatter: l.Formatter | None,
92
- should_install_traceback: bool,
93
- should_record: bool,
94
- rich_kwargs: dict[str, h.Any] | None,
62
+ kwargs,
95
63
  ) -> None:
96
64
  """"""
97
- l.Handler.__init__(self)
98
-
99
- self.extension = handler_extension_t(
100
- name=name,
101
- should_store_memory_usage=should_store_memory_usage,
102
- handler=self,
103
- level=level,
104
- message_width=message_width,
105
- formatter=formatter,
65
+ alternating_logs = kwargs.pop("alternating_logs", 0)
66
+ should_install_traceback = kwargs.pop("should_install_traceback", False)
67
+
68
+ assert alternating_logs in (0, 1, 2)
69
+
70
+ base_t.__init__(
71
+ self,
72
+ name,
73
+ should_store_memory_usage,
74
+ message_width,
75
+ level,
76
+ formatter,
77
+ kwargs,
106
78
  )
107
79
 
108
- if rich_kwargs is None:
109
- rich_console_kwargs = {}
110
- else:
111
- rich_console_kwargs = rich_kwargs
112
- rich_traceback_kwargs = {}
80
+ self.console = None # console_t | None.
81
+ self.alternating_logs = alternating_logs
82
+ self._log_parity = False
83
+
84
+ self.__post_init_local__(should_install_traceback, **kwargs)
85
+
86
+ def __post_init_local__(self, should_install_traceback: bool, **kwargs) -> None:
87
+ """"""
88
+ traceback_kwargs = {}
113
89
  if should_install_traceback:
114
- for key in rich_console_kwargs:
90
+ for key in kwargs:
115
91
  if key in _COMMON_TRACEBACK_ARGUMENTS:
116
- rich_traceback_kwargs[key] = rich_console_kwargs[key]
92
+ traceback_kwargs[key] = kwargs[key]
117
93
  elif key in _EXCLUSIVE_TRACEBACK_ARGUMENTS:
118
- rich_traceback_kwargs[key] = rich_console_kwargs[key]
119
- del rich_console_kwargs[key]
120
-
121
- self.console = console_t(
122
- highlight=False,
123
- force_terminal=True,
124
- record=should_record,
125
- **rich_console_kwargs,
126
- )
127
- if should_install_traceback:
128
- rich_traceback_kwargs["console"] = self.console
129
- InstallTracebackHandler(**rich_traceback_kwargs)
94
+ traceback_kwargs[key] = kwargs.pop(key)
130
95
 
131
- self.MessageFromRecord = self.extension.MessageFromRecord
132
- assert self.alternating_logs in (0, 1, 2)
96
+ self.console = console_t(highlight=False, force_terminal=True, **kwargs)
97
+
98
+ if should_install_traceback:
99
+ traceback_kwargs["console"] = self.console
100
+ InstallTracebackHandler(**traceback_kwargs)
101
+
102
+ @classmethod
103
+ def New(
104
+ cls,
105
+ /,
106
+ *,
107
+ name: str | None = None,
108
+ should_store_memory_usage: bool = False,
109
+ message_width: int = -1,
110
+ level: int = l.NOTSET,
111
+ formatter: l.Formatter | None = None,
112
+ **kwargs,
113
+ ) -> h.Self:
114
+ """"""
115
+ return cls(
116
+ name, should_store_memory_usage, message_width, level, formatter, kwargs
117
+ )
133
118
 
134
119
  def emit(self, record: l.LogRecord, /) -> None:
135
120
  """"""
136
- if hasattr(record, SHOW_W_RULE_ATTR):
137
- richer = Rule(record.msg, DATE_TIME_COLOR)
138
- else:
139
- message = self.MessageFromRecord(record, PreProcessed=EscapedVersion)
140
- richer = HighlightedVersion(
121
+ message, is_not_a_rule = self.MessageFromRecord(
122
+ record,
123
+ Rule,
124
+ line_width=self.message_width,
125
+ color=DATE_TIME_COLOR,
126
+ PreProcessed=EscapedVersion,
127
+ )
128
+ if is_not_a_rule:
129
+ message = HighlightedVersion(
141
130
  self.console,
142
131
  message,
143
132
  record.levelno,
144
133
  self.alternating_logs,
145
- self.log_parity,
134
+ self._log_parity,
146
135
  )
147
- self.console.print(richer, crop=False, overflow="ignore")
148
- self.log_parity = not self.log_parity
136
+ self.console.print(message, crop=False, overflow="ignore")
137
+ self._log_parity = not self._log_parity
149
138
 
150
139
  def LogAsIs(self, message: str | renderable_t, /) -> None:
151
- """
152
- See documentation of
153
- logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
154
- """
140
+ """"""
155
141
  self.console.print(message, crop=False, overflow="ignore")
156
142
 
157
- def DisplayRule(self, /, *, text: str | None = None, color: str = "white") -> None:
143
+ def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
158
144
  """"""
159
145
  self.LogAsIs(Rule(text, color))
160
146
 
@@ -0,0 +1,98 @@
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 logging as l
8
+ import typing as h
9
+ from pathlib import Path as path_t
10
+
11
+ from logger_36.task.format.rule import RuleAsText
12
+ from logger_36.type.handler import file_handler_t as base_t
13
+
14
+
15
+ class file_handler_t(base_t):
16
+ kind: h.ClassVar[str] = "f"
17
+
18
+ @classmethod
19
+ def New(
20
+ cls,
21
+ /,
22
+ *,
23
+ name: str | None = None,
24
+ should_store_memory_usage: bool = False,
25
+ message_width: int = -1,
26
+ level: int = l.NOTSET,
27
+ formatter: l.Formatter | None = None,
28
+ path: str | path_t | None = None,
29
+ **_,
30
+ ) -> h.Self:
31
+ """"""
32
+ return cls(
33
+ name, should_store_memory_usage, message_width, level, formatter, path
34
+ )
35
+
36
+ def emit(self, record: l.LogRecord, /) -> None:
37
+ """"""
38
+ message = self.MessageFromRecord(
39
+ record, RuleAsText, line_width=self.message_width
40
+ )
41
+ self.stream.write(message[0] + "\n")
42
+ self.stream.flush()
43
+
44
+ def LogAsIs(self, message: str, /) -> None:
45
+ """"""
46
+ self.stream.write(message + "\n")
47
+ self.stream.flush()
48
+
49
+ def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
50
+ """"""
51
+ self.LogAsIs(RuleAsText(text, None))
52
+
53
+
54
+ """
55
+ COPYRIGHT NOTICE
56
+
57
+ This software is governed by the CeCILL license under French law and
58
+ abiding by the rules of distribution of free software. You can use,
59
+ modify and/ or redistribute the software under the terms of the CeCILL
60
+ license as circulated by CEA, CNRS and INRIA at the following URL
61
+ "http://www.cecill.info".
62
+
63
+ As a counterpart to the access to the source code and rights to copy,
64
+ modify and redistribute granted by the license, users are provided only
65
+ with a limited warranty and the software's author, the holder of the
66
+ economic rights, and the successive licensors have only limited
67
+ liability.
68
+
69
+ In this respect, the user's attention is drawn to the risks associated
70
+ with loading, using, modifying and/or developing or reproducing the
71
+ software by the user in light of its specific status of free software,
72
+ that may mean that it is complicated to manipulate, and that also
73
+ therefore means that it is reserved for developers and experienced
74
+ professionals having in-depth computer knowledge. Users are therefore
75
+ encouraged to load and test the software's suitability as regards their
76
+ requirements in conditions enabling the security of their systems and/or
77
+ data to be ensured and, more generally, to use and operate it in the
78
+ same conditions as regards security.
79
+
80
+ The fact that you are presently reading this means that you have had
81
+ knowledge of the CeCILL license and that you accept its terms.
82
+
83
+ SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
84
+
85
+ This software is being developed by Eric Debreuve, a CNRS employee and
86
+ member of team Morpheme.
87
+ Team Morpheme is a joint team between Inria, CNRS, and UniCA.
88
+ It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
89
+ I3S, and Laboratory iBV.
90
+
91
+ CNRS: https://www.cnrs.fr/index.php/en
92
+ Inria: https://www.inria.fr/en/
93
+ UniCA: https://univ-cotedazur.eu/
94
+ Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
95
+ I3S: https://www.i3s.unice.fr/en/
96
+ iBV: http://ibv.unice.fr/
97
+ Team Morpheme: https://team.inria.fr/morpheme/
98
+ """
@@ -4,27 +4,26 @@ 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
8
  import typing as h
10
9
 
11
10
  from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
12
11
 
13
12
  if RICH_IS_AVAILABLE:
14
- from logger_36.catalog.config.console_rich import DATE_TIME_COLOR
15
- from logger_36.catalog.handler.console_rich import HighlightedVersion
16
13
  from rich.console import Console as console_t # noqa
17
14
  from rich.console import ConsoleOptions as console_options_t # noqa
18
15
  from rich.markup import escape as EscapedForRich # noqa
19
16
  from rich.terminal_theme import DEFAULT_TERMINAL_THEME # noqa
17
+
18
+ from logger_36.catalog.config.console_rich import DATE_TIME_COLOR
19
+ from logger_36.catalog.handler.console_rich import HighlightedVersion
20
20
  else:
21
21
  DATE_TIME_COLOR = HighlightedVersion = console_t = console_options_t = (
22
22
  EscapedForRich
23
23
  ) = DEFAULT_TERMINAL_THEME = None
24
24
 
25
- from logger_36.constant.record import SHOW_W_RULE_ATTR
26
- from logger_36.task.format.rule import Rule, RuleAsText
27
- from logger_36.type.handler import MessageFromRecord_h, handler_extension_t
25
+ from logger_36.task.format.rule import Rule, RuleAsText, rule_t
26
+ from logger_36.type.handler import handler_t as base_t
28
27
 
29
28
  LogAsIs_h = h.Callable[[str | h.Any], None]
30
29
 
@@ -34,11 +33,8 @@ class DisplayRule_p(h.Protocol):
34
33
  def __call__(self, /, *, text: str | None = None, color: str = "white") -> None: ...
35
34
 
36
35
 
37
- @d.dataclass(slots=True, repr=False, eq=False)
38
- class generic_handler_t(l.Handler):
36
+ class generic_handler_t(base_t):
39
37
  """
40
- kind: See logger_36.constant.handler.handler_codes_h.
41
-
42
38
  alternating_logs:
43
39
  - 0: disabled
44
40
  - 1: enabled for dark background
@@ -57,59 +53,45 @@ class generic_handler_t(l.Handler):
57
53
 
58
54
  kind: h.ClassVar[str] = "g"
59
55
 
60
- LogAsIs: LogAsIs_h
61
- # "None -> h.Any" (twice below) since None | None is invalid.
62
- console: console_t | h.Any = None
63
- console_options: console_options_t | h.Any = None
64
- alternating_logs: int = 0
65
-
66
- DisplayRule: DisplayRule_p = d.field(init=False)
67
- extension: handler_extension_t = d.field(init=False)
68
- MessageFromRecord: MessageFromRecord_h = d.field(init=False)
69
- log_parity: bool = d.field(init=False, default=False)
70
-
71
- name: d.InitVar[str | None] = None
72
- level: d.InitVar[int] = l.NOTSET
73
- should_store_memory_usage: d.InitVar[bool] = False
74
- message_width: d.InitVar[int] = -1
75
- formatter: d.InitVar[l.Formatter | None] = None
76
- #
77
- supports_html: d.InitVar[bool] = False
78
- should_record: d.InitVar[bool] = False
79
- rich_kwargs: d.InitVar[dict[str, h.Any] | None] = None
80
-
81
- def __post_init__(
56
+ def __init__(
82
57
  self,
83
58
  name: str | None,
84
- level: int,
85
59
  should_store_memory_usage: bool,
86
60
  message_width: int,
61
+ level: int,
87
62
  formatter: l.Formatter | None,
88
- supports_html: bool,
89
- should_record: bool,
90
- rich_kwargs: dict[str, h.Any] | None,
63
+ kwargs,
91
64
  ) -> None:
92
65
  """"""
93
- l.Handler.__init__(self)
94
-
95
- self.extension = handler_extension_t(
96
- name=name,
97
- should_store_memory_usage=should_store_memory_usage,
98
- handler=self,
99
- level=level,
100
- message_width=message_width,
101
- formatter=formatter,
66
+ alternating_logs = kwargs.pop("alternating_logs", 0)
67
+ LogAsIs = kwargs.pop("LogAsIs", lambda _, indented=False: print(_))
68
+ supports_html = kwargs.pop("supports_html", False)
69
+
70
+ assert alternating_logs in (0, 1, 2)
71
+
72
+ base_t.__init__(
73
+ self,
74
+ name,
75
+ should_store_memory_usage,
76
+ message_width,
77
+ level,
78
+ formatter,
79
+ kwargs,
102
80
  )
103
81
 
82
+ self.LogAsIs = LogAsIs
83
+ self.DisplayRule = None # DisplayRule_p | None.
84
+ self.console = None # console_t | None.
85
+ self.console_options = None # console_options_t | None.
86
+ self.alternating_logs = alternating_logs
87
+ self._log_parity = False
88
+
89
+ self.__post_init_local__(supports_html)
90
+
91
+ def __post_init_local__(self, supports_html: bool) -> None:
92
+ """"""
104
93
  if supports_html and (console_t is not None):
105
- if rich_kwargs is None:
106
- rich_kwargs = {}
107
- self.console = console_t(
108
- highlight=False,
109
- force_terminal=True,
110
- record=should_record,
111
- **rich_kwargs,
112
- )
94
+ self.console = console_t(highlight=False, force_terminal=True)
113
95
  self.console_options = self.console.options.update(
114
96
  overflow="ignore", no_wrap=True
115
97
  )
@@ -117,29 +99,46 @@ class generic_handler_t(l.Handler):
117
99
  else:
118
100
  self.DisplayRule = self._DisplayRuleAsText
119
101
 
120
- self.MessageFromRecord = self.extension.MessageFromRecord
121
- assert self.alternating_logs in (0, 1, 2)
102
+ @classmethod
103
+ def New(
104
+ cls,
105
+ /,
106
+ *,
107
+ name: str | None = None,
108
+ should_store_memory_usage: bool = False,
109
+ message_width: int = -1,
110
+ level: int = l.NOTSET,
111
+ formatter: l.Formatter | None = None,
112
+ **kwargs,
113
+ ) -> h.Self:
114
+ """"""
115
+ return cls(
116
+ name, should_store_memory_usage, message_width, level, formatter, kwargs
117
+ )
122
118
 
123
119
  def emit(self, record: l.LogRecord, /) -> None:
124
120
  """"""
125
121
  if self.console is None:
126
- if hasattr(record, SHOW_W_RULE_ATTR):
127
- message = RuleAsText(record.msg)
128
- else:
129
- message = self.MessageFromRecord(record)
122
+ message = self.MessageFromRecord(
123
+ record, RuleAsText, line_width=self.message_width
124
+ )[0]
130
125
  else:
131
- if hasattr(record, SHOW_W_RULE_ATTR):
132
- richer = Rule(record.msg, DATE_TIME_COLOR)
133
- else:
134
- message = self.MessageFromRecord(record, PreProcessed=EscapedForRich)
135
- richer = HighlightedVersion(
126
+ message, is_not_a_rule = self.MessageFromRecord(
127
+ record,
128
+ Rule,
129
+ line_width=self.message_width,
130
+ color=DATE_TIME_COLOR,
131
+ PreProcessed=EscapedForRich,
132
+ )
133
+ if is_not_a_rule:
134
+ message = HighlightedVersion(
136
135
  self.console,
137
136
  message,
138
137
  record.levelno,
139
138
  self.alternating_logs,
140
- self.log_parity,
139
+ self._log_parity,
141
140
  )
142
- segments = self.console.render(richer, options=self.console_options)
141
+ segments = self.console.render(message, options=self.console_options)
143
142
 
144
143
  # Inspired from the code of: rich.console.export_html.
145
144
  html_segments = []
@@ -164,13 +163,13 @@ class generic_handler_t(l.Handler):
164
163
  )
165
164
 
166
165
  self.LogAsIs(message)
167
- self.log_parity = not self.log_parity
166
+ self._log_parity = not self._log_parity
168
167
 
169
168
  def _DisplayRuleAsText(
170
169
  self, /, *, text: str | None = None, color: str = "white"
171
170
  ) -> None:
172
171
  """"""
173
- self.LogAsIs(RuleAsText(text))
172
+ self.LogAsIs(RuleAsText(text, None))
174
173
 
175
174
  def _DisplayRule(self, /, *, text: str | None = None, color: str = "white") -> None:
176
175
  """"""
@@ -39,7 +39,7 @@ def LogGPURelatedDetails(*, logger: logger_t = L) -> None:
39
39
  f" CuDNN: {system_details['cudnn_version']}\n"
40
40
  f" Tensorflow: {tsfl.version.VERSION}\n"
41
41
  f" Tensorflow Build: {tsfl.sysconfig.get_build_info()}\n"
42
- f" TensorRT: {tsrt.__version__}",
42
+ f" TensorRT: {tsrt.__version__}"
43
43
  )
44
44
 
45
45
 
@@ -33,7 +33,7 @@ def LogSystemDetails(
33
33
  f"SYSTEM DETAILS\n"
34
34
  f"{details}\n"
35
35
  f" {'Python Modules':>{MAX_DETAIL_NAME_LENGTH}}:\n"
36
- f"{modules}",
36
+ f"{modules}"
37
37
  )
38
38
 
39
39
 
@@ -11,6 +11,7 @@ LEVEL_CLOSING = ")"
11
11
  MESSAGE_MARKER = "|"
12
12
  WHERE_SEPARATOR = "@"
13
13
  ELAPSED_TIME_SEPARATOR = "+"
14
+ FALLBACK_MESSAGE_WIDTH = 5
14
15
 
15
16
  DATE_FORMAT = "%Y-%m-%d"
16
17
  TIME_FORMAT = "%H:%M:%S"