logger-36 2024.1__py3-none-any.whl → 2025.4__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. logger_36/__init__.py +64 -42
  2. logger_36/api/logger.py +53 -0
  3. logger_36/api/storage.py +53 -0
  4. logger_36/catalog/config/console_rich.py +76 -0
  5. logger_36/catalog/handler/console.py +117 -0
  6. logger_36/catalog/handler/console_rich.py +235 -0
  7. logger_36/catalog/handler/file.py +128 -0
  8. logger_36/catalog/handler/generic.py +230 -0
  9. logger_36/catalog/logger/chronos.py +61 -0
  10. logger_36/catalog/logger/gpu.py +90 -0
  11. logger_36/catalog/logger/memory.py +129 -0
  12. logger_36/catalog/logger/system.py +84 -0
  13. logger_36/config/issue.py +56 -0
  14. logger_36/config/logger.py +103 -0
  15. logger_36/config/memory.py +54 -0
  16. logger_36/config/message.py +66 -0
  17. logger_36/config/system.py +70 -0
  18. logger_36/constant/error.py +70 -0
  19. logger_36/constant/generic.py +58 -0
  20. logger_36/constant/handler.py +58 -0
  21. logger_36/constant/issue.py +58 -0
  22. logger_36/constant/logger.py +67 -0
  23. logger_36/constant/memory.py +58 -0
  24. logger_36/constant/message.py +72 -0
  25. logger_36/constant/record.py +55 -0
  26. logger_36/constant/system.py +60 -0
  27. logger_36/content.py +55 -0
  28. logger_36/exception.py +105 -0
  29. logger_36/gpu.py +53 -0
  30. logger_36/handler.py +209 -0
  31. logger_36/instance/logger.py +55 -0
  32. logger_36/instance/loggers.py +56 -0
  33. logger_36/memory.py +60 -0
  34. logger_36/storage.py +53 -0
  35. logger_36/system.py +53 -0
  36. logger_36/task/format/memory.py +132 -0
  37. logger_36/task/format/message.py +111 -0
  38. logger_36/task/format/rule.py +74 -0
  39. logger_36/task/inspection.py +70 -48
  40. logger_36/task/measure/chronos.py +84 -0
  41. logger_36/task/measure/memory.py +72 -0
  42. logger_36/task/storage.py +127 -46
  43. logger_36/time.py +54 -0
  44. logger_36/type/handler.py +184 -0
  45. logger_36/type/issue.py +91 -0
  46. logger_36/type/logger.py +542 -0
  47. logger_36/type/loggers.py +78 -0
  48. logger_36/version.py +53 -32
  49. logger_36-2025.4.dist-info/METADATA +154 -0
  50. logger_36-2025.4.dist-info/RECORD +52 -0
  51. {logger_36-2024.1.dist-info → logger_36-2025.4.dist-info}/WHEEL +1 -1
  52. logger_36/catalog/gpu.py +0 -56
  53. logger_36/catalog/memory.py +0 -109
  54. logger_36/catalog/system.py +0 -84
  55. logger_36/config.py +0 -48
  56. logger_36/constant.py +0 -52
  57. logger_36/instance.py +0 -34
  58. logger_36/main.py +0 -96
  59. logger_36/measure/chronos.py +0 -55
  60. logger_36/measure/memory.py +0 -50
  61. logger_36/type/console.py +0 -122
  62. logger_36/type/extension.py +0 -122
  63. logger_36/type/file.py +0 -52
  64. logger_36/type/generic.py +0 -115
  65. logger_36-2024.1.dist-info/METADATA +0 -106
  66. logger_36-2024.1.dist-info/RECORD +0 -21
  67. {logger_36-2024.1.dist-info → logger_36-2025.4.dist-info}/top_level.txt +0 -0
logger_36/instance.py DELETED
@@ -1,34 +0,0 @@
1
- # eric.debreuve@cnrs.fr
2
- #
3
- # This software is governed by the CeCILL license under French law and
4
- # abiding by the rules of distribution of free software. You can use,
5
- # modify and/ or redistribute the software under the terms of the CeCILL
6
- # license as circulated by CEA, CNRS and INRIA at the following URL
7
- # "http://www.cecill.info".
8
- #
9
- # As a counterpart to the access to the source code and rights to copy,
10
- # modify and redistribute granted by the license, users are provided only
11
- # with a limited warranty and the software's author, the holder of the
12
- # economic rights, and the successive licensors have only limited
13
- # liability.
14
- #
15
- # In this respect, the user's attention is drawn to the risks associated
16
- # with loading, using, modifying and/or developing or reproducing the
17
- # software by the user in light of its specific status of free software,
18
- # that may mean that it is complicated to manipulate, and that also
19
- # therefore means that it is reserved for developers and experienced
20
- # professionals having in-depth computer knowledge. Users are therefore
21
- # encouraged to load and test the software's suitability as regards their
22
- # requirements in conditions enabling the security of their systems and/or
23
- # data to be ensured and, more generally, to use and operate it in the
24
- # same conditions as regards security.
25
- #
26
- # The fact that you are presently reading this means that you have had
27
- # knowledge of the CeCILL license and that you accept its terms.
28
-
29
- import logging as lggg
30
-
31
- from logger_36.config import LOGGER_NAME
32
-
33
- LOGGER = lggg.getLogger(name=LOGGER_NAME)
34
- LOGGER.setLevel(lggg.DEBUG)
logger_36/main.py DELETED
@@ -1,96 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- """
33
- Alternative implementations: using logging.Filter or logging.LoggerAdapter.
34
- """
35
- import logging as lggg
36
- from pathlib import Path as path_t
37
- from typing import Callable, Literal
38
-
39
- from logger_36.instance import LOGGER
40
- from logger_36.type.console import console_handler_t
41
- from logger_36.type.file import file_handler_t
42
- from logger_36.type.generic import can_show_message_p, generic_handler_t
43
-
44
-
45
- def AddGenericHandler(
46
- interface: can_show_message_p | Callable[[str], None],
47
- /,
48
- *args,
49
- level: int = lggg.INFO,
50
- supports_html: bool = False,
51
- **kwargs,
52
- ) -> None:
53
- """"""
54
- handler = generic_handler_t(interface, *args, supports_html=supports_html, **kwargs)
55
- handler.setLevel(level)
56
- LOGGER.addHandler(handler)
57
-
58
-
59
- def AddFileHandler(
60
- path: str | path_t, /, *args, level: int = lggg.INFO, **kwargs
61
- ) -> None:
62
- """"""
63
- if isinstance(path, str):
64
- path = path_t(path)
65
- if path.exists():
66
- raise ValueError(f"{path}: File already exists")
67
-
68
- handler = file_handler_t(path, *args, **kwargs)
69
- handler.setLevel(level)
70
- LOGGER.addHandler(handler)
71
-
72
-
73
- def SetLOGLevel(level: int, /, *, which: Literal["c", "f", "a"] = "a") -> None:
74
- """
75
- which: c=console, f=file, a=all
76
- """
77
- if which not in "cfa":
78
- raise ValueError(
79
- f"{which}: Invalid handler specifier. "
80
- f'Expected="c" for console, "f" for file, or "a" for all'
81
- )
82
-
83
- for handler in LOGGER.handlers:
84
- if (
85
- (which == "a")
86
- or ((which == "c") and isinstance(handler, console_handler_t))
87
- or ((which == "f") and isinstance(handler, file_handler_t))
88
- ):
89
- handler.setLevel(level)
90
-
91
-
92
- def SetExitOnError(exit_on_error: bool, /) -> None:
93
- """"""
94
- for handler in LOGGER.handlers:
95
- if hasattr(handler, "exit_on_error"):
96
- handler.exit_on_error = exit_on_error
@@ -1,55 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- import time
33
- from datetime import datetime as dttm
34
-
35
- from logger_36.constant import START_TIME
36
-
37
-
38
- def TimeStamp() -> str:
39
- """"""
40
- return (
41
- dttm.now()
42
- .isoformat(timespec="milliseconds")
43
- .replace(".", "-")
44
- .replace(":", "-")
45
- )
46
-
47
-
48
- def ElapsedTime() -> str:
49
- """"""
50
- elapsed_seconds = (dttm.now() - START_TIME).total_seconds()
51
- output = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_seconds))
52
- while output.startswith("00") and (" " in output):
53
- output = output.split(maxsplit=1)[-1]
54
-
55
- return output
@@ -1,50 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- try:
33
- from psutil import Process as process_t
34
-
35
- _PROCESS = process_t()
36
- except ModuleNotFoundError:
37
- _PROCESS = None
38
-
39
-
40
- def CanCheckMemory() -> bool:
41
- """"""
42
- return _PROCESS is not None
43
-
44
-
45
- def CurrentUsage() -> int:
46
- """"""
47
- if _PROCESS is None:
48
- return -1
49
-
50
- return _PROCESS.memory_info().rss
logger_36/type/console.py DELETED
@@ -1,122 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- import logging as lggg
33
- from typing import ClassVar
34
-
35
- from rich.color import Color as color_t
36
- from rich.console import Console as console_t
37
- from rich.markup import escape as PreProcessedForRich
38
- from rich.style import Style as style_t
39
- from rich.text import Text as text_t
40
-
41
- from logger_36.config import ELAPSED_TIME_SEPARATOR, LEVEL_CLOSING, WHERE_SEPARATOR
42
- from logger_36.constant import DATE_TIME_LENGTH
43
- from logger_36.type.extension import handler_extension_t
44
-
45
-
46
- class console_handler_t(lggg.Handler, handler_extension_t):
47
- TAB_SIZE: ClassVar[int] = 5 # => CONTEXT_SEPARATOR aligned for all log levels.
48
- DATE_TIME_COLOR: ClassVar[str] = "dodger_blue2"
49
- LEVEL_COLOR: ClassVar[dict[int, str | style_t]] = {
50
- lggg.DEBUG: "orchid",
51
- lggg.INFO: "white",
52
- lggg.WARNING: "yellow",
53
- lggg.ERROR: "orange1",
54
- lggg.CRITICAL: "red",
55
- }
56
- ELAPSED_TIME_COLOR: ClassVar[str] = "green"
57
- ACTUAL_COLOR: ClassVar[str] = "red"
58
- EXPECTED_COLOR: ClassVar[str] = "green"
59
- GRAY_STYLE: ClassVar[style_t] = style_t(color=color_t.from_rgb(150, 150, 150))
60
- ACTUAL_PATTERNS: ClassVar[tuple[str]] = (r" Actual=[^.]+;",)
61
- EXPECTED_PATTERNS: ClassVar[tuple[str]] = (r" Expected([!<>]=|: )[^.]+\.",)
62
-
63
- console: console_t
64
-
65
- def __init__(self, /, *, level: int = lggg.NOTSET) -> None:
66
- """"""
67
- lggg.Handler.__init__(self, level=level)
68
- handler_extension_t.__init__(self)
69
-
70
- self.setFormatter(self.formatter)
71
- self.console = console_t(
72
- tab_size=self.__class__.TAB_SIZE,
73
- highlight=False,
74
- force_terminal=True,
75
- record=True,
76
- )
77
-
78
- def emit(self, record: lggg.LogRecord, /) -> None:
79
- """"""
80
- first_line, next_lines = self.MessageLines(
81
- record, PreProcessed=PreProcessedForRich
82
- )
83
- highlighted = self.__class__.HighlightedVersion(
84
- first_line, next_lines, record.levelno
85
- )
86
- self.console.print(highlighted, crop=False, overflow="ignore")
87
-
88
- self.ExitOrNotIfError(record)
89
-
90
- @classmethod
91
- def HighlightedVersion(
92
- cls, first_line: str, next_lines: str | None, log_level: int, /
93
- ) -> text_t:
94
- """"""
95
- output = text_t(first_line)
96
-
97
- # Used instead of _CONTEXT_LENGTH which might include \t, thus creating a
98
- # mismatch between character length and length when displayed in console.
99
- context_end = first_line.find(LEVEL_CLOSING)
100
- elapsed_time_separator = first_line.rfind(ELAPSED_TIME_SEPARATOR)
101
- where_separator = first_line.rfind(
102
- WHERE_SEPARATOR, context_end, elapsed_time_separator
103
- )
104
-
105
- output.stylize(cls.DATE_TIME_COLOR, end=DATE_TIME_LENGTH)
106
- output.stylize(
107
- cls.LEVEL_COLOR[log_level],
108
- start=DATE_TIME_LENGTH,
109
- end=context_end + 1,
110
- )
111
- output.stylize(
112
- cls.GRAY_STYLE, start=where_separator, end=elapsed_time_separator
113
- )
114
- output.stylize(cls.ELAPSED_TIME_COLOR, start=elapsed_time_separator)
115
-
116
- if next_lines is not None:
117
- output.append(next_lines)
118
-
119
- output.highlight_words(cls.ACTUAL_PATTERNS, style=cls.ACTUAL_COLOR)
120
- output.highlight_words(cls.EXPECTED_PATTERNS, style=cls.EXPECTED_COLOR)
121
-
122
- return output
@@ -1,122 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- import logging as lggg
33
- import sys as sstm
34
- from typing import Callable
35
-
36
- from logger_36.catalog.memory import WithAutoUnit as MemoryWithAutoUnit
37
- from logger_36.config import DATE_TIME_FORMAT, MESSAGE_FORMAT
38
- from logger_36.constant import LOG_LEVEL_LENGTH, NEXT_LINE_PROLOGUE
39
- from logger_36.measure.chronos import ElapsedTime
40
- from logger_36.measure.memory import CurrentUsage as CurrentMemoryUsage
41
-
42
-
43
- class handler_extension_t:
44
- __slots__ = ("formatter", "show_memory_usage", "max_memory_usage", "exit_on_error")
45
- formatter: lggg.Formatter
46
- show_memory_usage: bool
47
- max_memory_usage: int
48
- exit_on_error: bool
49
-
50
- def __init__(self) -> None:
51
- """"""
52
- self.formatter = lggg.Formatter(fmt=MESSAGE_FORMAT, datefmt=DATE_TIME_FORMAT)
53
- self.show_memory_usage = False
54
- self.max_memory_usage = -1
55
- self.exit_on_error = False
56
-
57
- def MessageLines(
58
- self,
59
- record: lggg.LogRecord,
60
- /,
61
- *,
62
- PreProcessed: Callable[[str], str] | None = None,
63
- should_fully_format: bool = False,
64
- ) -> tuple[str, str | None]:
65
- """
66
- Note: "message" is not yet an attribute of record (it will be set by format());
67
- Use "msg" instead.
68
- """
69
- if not isinstance(record.msg, str):
70
- record.msg = str(record.msg)
71
- if PreProcessed is not None:
72
- record.msg = PreProcessed(record.msg)
73
- if "\n" in record.msg:
74
- original_message = record.msg
75
- lines = original_message.splitlines()
76
- record.msg = lines[0]
77
- next_lines = NEXT_LINE_PROLOGUE.join(lines[1:])
78
- next_lines = f"{NEXT_LINE_PROLOGUE}{next_lines}"
79
- else:
80
- original_message = next_lines = None
81
-
82
- # The record is shared between handlers, so do not re-assign if already there.
83
- if not hasattr(record, "elapsed_time"):
84
- record.elapsed_time = ElapsedTime()
85
- # Re-assign for each handler in case they have different show properties.
86
- if self.show_memory_usage:
87
- record.memory_usage = self.FormattedMemoryUsage()
88
- else:
89
- record.memory_usage = ""
90
-
91
- padding = (LOG_LEVEL_LENGTH - record.levelname.__len__() - 1) * " "
92
- first_line = self.formatter.format(record).replace("\t", padding)
93
-
94
- # Revert the record message to its original value for subsequent handlers.
95
- if original_message is not None:
96
- record.msg = original_message
97
-
98
- if should_fully_format:
99
- if next_lines is None:
100
- return first_line, None
101
- else:
102
- return f"{first_line}{next_lines}", None
103
- else:
104
- return first_line, next_lines
105
-
106
- def FormattedMemoryUsage(self) -> str:
107
- """"""
108
- if self.show_memory_usage:
109
- usage = CurrentMemoryUsage()
110
- if usage > self.max_memory_usage:
111
- self.max_memory_usage = usage
112
-
113
- usage, unit = MemoryWithAutoUnit(usage, 1)
114
-
115
- return f" :{usage}{unit}"
116
- else:
117
- return ""
118
-
119
- def ExitOrNotIfError(self, record: lggg.LogRecord, /) -> None:
120
- """"""
121
- if self.exit_on_error and (record.levelno in (lggg.ERROR, lggg.CRITICAL)):
122
- sstm.exit(1)
logger_36/type/file.py DELETED
@@ -1,52 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- import logging as lggg
33
- from pathlib import Path as path_t
34
-
35
- from logger_36.type.extension import handler_extension_t
36
-
37
-
38
- class file_handler_t(lggg.FileHandler, handler_extension_t):
39
- def __init__(self, path: str | path_t, /, *args, **kwargs) -> None:
40
- """"""
41
- lggg.FileHandler.__init__(self, str(path), *args, **kwargs)
42
- handler_extension_t.__init__(self)
43
-
44
- self.setFormatter(self.formatter)
45
-
46
- def emit(self, record: lggg.LogRecord, /) -> None:
47
- """"""
48
- message, _ = self.MessageLines(record, should_fully_format=True)
49
- print(message, file=self.stream)
50
- self.stream.flush()
51
-
52
- self.ExitOrNotIfError(record)
logger_36/type/generic.py DELETED
@@ -1,115 +0,0 @@
1
- # Copyright CNRS/Inria/UCA
2
- # Contributor(s): Eric Debreuve (since 2023)
3
- #
4
- # eric.debreuve@cnrs.fr
5
- #
6
- # This software is governed by the CeCILL license under French law and
7
- # abiding by the rules of distribution of free software. You can use,
8
- # modify and/ or redistribute the software under the terms of the CeCILL
9
- # license as circulated by CEA, CNRS and INRIA at the following URL
10
- # "http://www.cecill.info".
11
- #
12
- # As a counterpart to the access to the source code and rights to copy,
13
- # modify and redistribute granted by the license, users are provided only
14
- # with a limited warranty and the software's author, the holder of the
15
- # economic rights, and the successive licensors have only limited
16
- # liability.
17
- #
18
- # In this respect, the user's attention is drawn to the risks associated
19
- # with loading, using, modifying and/or developing or reproducing the
20
- # software by the user in light of its specific status of free software,
21
- # that may mean that it is complicated to manipulate, and that also
22
- # therefore means that it is reserved for developers and experienced
23
- # professionals having in-depth computer knowledge. Users are therefore
24
- # encouraged to load and test the software's suitability as regards their
25
- # requirements in conditions enabling the security of their systems and/or
26
- # data to be ensured and, more generally, to use and operate it in the
27
- # same conditions as regards security.
28
- #
29
- # The fact that you are presently reading this means that you have had
30
- # knowledge of the CeCILL license and that you accept its terms.
31
-
32
- import logging as lggg
33
- from typing import Callable, Protocol
34
-
35
- from rich.console import Console as console_t
36
- from rich.markup import escape as PreProcessedForRich
37
- from rich.terminal_theme import DEFAULT_TERMINAL_THEME
38
-
39
- from logger_36.type.console import console_handler_t
40
- from logger_36.type.extension import handler_extension_t
41
-
42
-
43
- class can_show_message_p(Protocol):
44
- def Show(self, message: str, /) -> None: ...
45
-
46
-
47
- class generic_handler_t(lggg.Handler, handler_extension_t):
48
- __slots__ = ("console", "Show")
49
- console: console_t | None
50
- Show: Callable[[str], None]
51
-
52
- def __init__(
53
- self,
54
- interface: can_show_message_p | Callable[[str], None],
55
- /,
56
- *args,
57
- supports_html: bool = False,
58
- **kwargs,
59
- ) -> None:
60
- """"""
61
- lggg.Handler.__init__(self, *args, **kwargs)
62
- handler_extension_t.__init__(self)
63
-
64
- if supports_html:
65
- self.console = console_t(
66
- tab_size=console_handler_t.TAB_SIZE,
67
- highlight=False,
68
- force_terminal=True,
69
- )
70
- else:
71
- self.console = None
72
- if hasattr(interface, "Show"):
73
- self.Show = interface.Show
74
- else:
75
- self.Show = interface
76
- self.setFormatter(self.formatter)
77
-
78
- def emit(self, record: lggg.LogRecord, /) -> None:
79
- """"""
80
- if self.console is None:
81
- message, _ = self.MessageLines(record, should_fully_format=True)
82
- else:
83
- first_line, next_lines = self.MessageLines(
84
- record, PreProcessed=PreProcessedForRich
85
- )
86
- highlighted = console_handler_t.HighlightedVersion(
87
- first_line, next_lines, record.levelno
88
- )
89
- segments = self.console.render(highlighted)
90
-
91
- # Inspired from the code of: rich.console.export_html.
92
- html_segments = []
93
- for text, style, _ in segments:
94
- if text == "\n":
95
- html_segments.append("\n")
96
- else:
97
- if style is not None:
98
- style = style.get_html_style(DEFAULT_TERMINAL_THEME)
99
- if (style is not None) and (style.__len__() > 0):
100
- text = f'<span style="{style}">{text}</span>'
101
- html_segments.append(text)
102
- if html_segments[-1] == "\n":
103
- html_segments = html_segments[:-1]
104
-
105
- # /!\ For some reason, the widget splits the message into lines, place each line
106
- # inside a pre tag, and set margin-bottom of the first and list lines to 12px.
107
- # This can be seen by printing self.contents.toHtml(). To avoid the unwanted
108
- # extra margins, margin-bottom is set to 0 below.
109
- message = (
110
- "<pre style='margin-bottom:0px'>" + "".join(html_segments) + "</pre>"
111
- )
112
-
113
- self.Show(message)
114
-
115
- self.ExitOrNotIfError(record)