logger-36 2025.15__py3-none-any.whl → 2025.16__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/type/logger.py CHANGED
@@ -8,6 +8,7 @@ import dataclasses as d
8
8
  import logging as l
9
9
  import sys as s
10
10
  import textwrap as text
11
+ import threading as thrd
11
12
  import traceback as tcbk
12
13
  import types as t
13
14
  import typing as h
@@ -43,7 +44,6 @@ from logger_36.constant.record import (
43
44
  SHOW_W_RULE_ATTR,
44
45
  STORE_MEMORY_ATTR,
45
46
  )
46
- from logger_36.extension.exception import OverrideExceptionFormat
47
47
  from logger_36.task.format.message import MessageFromRecord, MessageWithActualExpected
48
48
  from logger_36.task.format.rule import RuleAsText
49
49
  from logger_36.task.measure.chronos import ElapsedTime
@@ -101,6 +101,7 @@ class logger_t(base_t):
101
101
  intercepted_log_handles: dict[str, logger_handle_h] = d.field(
102
102
  init=False, default_factory=dict
103
103
  )
104
+ intercepts_exceptions: bool = d.field(init=False, default=False)
104
105
  _on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list)
105
106
  _should_hold_messages: bool = d.field(init=False, default=True)
106
107
  _should_activate_log_interceptions: bool = d.field(init=False, default=False)
@@ -109,6 +110,7 @@ class logger_t(base_t):
109
110
  level_: d.InitVar[int] = l.NOTSET
110
111
  activate_wrn_interceptions: d.InitVar[bool] = True
111
112
  activate_log_interceptions: d.InitVar[bool] = True
113
+ activate_exc_interceptions: d.InitVar[bool] = True
112
114
 
113
115
  @property
114
116
  def intercepts_warnings(self) -> bool:
@@ -154,6 +156,7 @@ class logger_t(base_t):
154
156
  level_: int,
155
157
  activate_wrn_interceptions: bool,
156
158
  activate_log_interceptions: bool,
159
+ activate_exc_interceptions: bool,
157
160
  ) -> None:
158
161
  """"""
159
162
  base_t.__init__(self, name_)
@@ -169,6 +172,8 @@ class logger_t(base_t):
169
172
  self.ToggleWarningInterceptions(True)
170
173
  if activate_log_interceptions:
171
174
  self._should_activate_log_interceptions = True
175
+ if activate_exc_interceptions:
176
+ self.ToggleExceptionInterceptions(True)
172
177
 
173
178
  if self.exit_on_error:
174
179
  self.exit_on_critical = True
@@ -296,7 +301,6 @@ class logger_t(base_t):
296
301
 
297
302
  def MakeMonochrome(self) -> None:
298
303
  """"""
299
- OverrideExceptionFormat()
300
304
  self.AddHandler(console_handler_t)
301
305
 
302
306
  def MakeRich(self, *, alternating_logs: int = 0) -> None:
@@ -304,7 +308,6 @@ class logger_t(base_t):
304
308
  if MISSING_RICH_MESSAGE is not None:
305
309
  s.__stderr__.write(MISSING_RICH_MESSAGE + "\n")
306
310
 
307
- OverrideExceptionFormat()
308
311
  if console_rich_handler_t is console_handler_t:
309
312
  handler_kwargs = {}
310
313
  else:
@@ -313,7 +316,6 @@ class logger_t(base_t):
313
316
 
314
317
  def MakePermanent(self, path: str | path_t, /) -> None:
315
318
  """"""
316
- OverrideExceptionFormat()
317
319
  self.AddHandler(file_handler_t, path=path)
318
320
 
319
321
  def ResetEventCounts(self) -> None:
@@ -377,6 +379,37 @@ class logger_t(base_t):
377
379
  self.intercepted_log_handles.clear()
378
380
  self.info("Log Interception: OFF")
379
381
 
382
+ def ToggleExceptionInterceptions(self, state: bool, /) -> None:
383
+ """"""
384
+ if state:
385
+ if self.intercepts_exceptions:
386
+ return
387
+
388
+ s.excepthook = self.DealWithException
389
+ thrd.excepthook = self.DealWithExceptionInThread
390
+ self.intercepts_exceptions = True
391
+ self.info("Exception Interception: ON")
392
+ else:
393
+ if not self.intercepts_exceptions:
394
+ return
395
+
396
+ s.excepthook = s.__excepthook__
397
+ thrd.excepthook = thrd.__excepthook__
398
+ self.intercepts_exceptions = False
399
+ self.info("Exception Interception: OFF")
400
+
401
+ def DealWithException(self, _, exc_value, exc_traceback, /) -> None:
402
+ """"""
403
+ exception = exc_value.with_traceback(exc_traceback)
404
+ self.LogException(exception, level=l.CRITICAL)
405
+ s.exit(1)
406
+
407
+ def DealWithExceptionInThread(
408
+ self, exc_type, exc_value, exc_traceback, _, /
409
+ ) -> None:
410
+ """"""
411
+ self.DealWithException(exc_type, exc_value, exc_traceback)
412
+
380
413
  def AddHandler(
381
414
  self,
382
415
  handler_t: type[base_handler_t],
@@ -476,8 +509,8 @@ class logger_t(base_t):
476
509
  # - Why it's not: "\n".join(lines)?
477
510
  # - Why adding exception name here and not when removing caller?
478
511
  formatted = "".join(lines)
479
- message = f"{type(exception).__name__}:\n{formatted}"
480
- self.log(level, message)
512
+ message = f"Exception of type {type(exception).__name__}\n----\n{formatted}"
513
+ self.log(level, message, extra={HIDE_WHERE_ATTR: None})
481
514
 
482
515
  def LogAsIs(self, message: str, /, *, indented: bool = False) -> None:
483
516
  """"""
logger_36/type/loggers.py CHANGED
@@ -5,8 +5,10 @@ SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
7
  import dataclasses as d
8
+ import logging as l
8
9
  import typing as h
9
10
 
11
+ from logger_36.constant.logger import LOGGER_NAME
10
12
  from logger_36.type.logger import logger_t
11
13
 
12
14
 
@@ -14,9 +16,32 @@ from logger_36.type.logger import logger_t
14
16
  class loggers_t(dict[h.Hashable, logger_t]):
15
17
  active: logger_t | None = d.field(init=False, default=None)
16
18
 
17
- def AddNew(self, uid: h.Hashable, /) -> None:
19
+ def AddNew(
20
+ self,
21
+ uid: h.Hashable,
22
+ /,
23
+ *,
24
+ name: str = LOGGER_NAME,
25
+ level: int = l.NOTSET,
26
+ should_record_messages: bool = False,
27
+ exit_on_error: bool = False,
28
+ exit_on_critical: bool = False,
29
+ activate_wrn_interceptions: bool = True,
30
+ activate_log_interceptions: bool = True,
31
+ activate_exc_interceptions: bool = True,
32
+ ) -> None:
18
33
  """"""
19
- self.Add(uid, logger_t())
34
+ logger = logger_t(
35
+ should_record_messages=should_record_messages,
36
+ exit_on_error=exit_on_error,
37
+ exit_on_critical=exit_on_critical,
38
+ name_=name,
39
+ level_=level,
40
+ activate_wrn_interceptions=activate_wrn_interceptions,
41
+ activate_log_interceptions=activate_log_interceptions,
42
+ activate_exc_interceptions=activate_exc_interceptions,
43
+ )
44
+ self.Add(uid, logger)
20
45
 
21
46
  def Add(self, uid: h.Hashable, logger: logger_t, /) -> None:
22
47
  """"""
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.15"
7
+ __version__ = "2025.16"
8
8
 
9
9
  """
10
10
  COPYRIGHT NOTICE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logger-36
3
- Version: 2025.15
3
+ Version: 2025.16
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,7 +1,6 @@
1
1
  logger_36/__init__.py,sha256=UhKxuQLS1Pfgt5H0K_7BaDAPejOUR8byD5BYRCnHQMQ,2655
2
- logger_36/version.py,sha256=oFhR-WWJSP1I096JdyMWykVW-yQE68ygNDxM43rM030,2206
2
+ logger_36/version.py,sha256=vxBUi_PLey0-7pBB4KEVJ1RP-m_hqLO7B8S6ifB0twk,2206
3
3
  logger_36/api/content.py,sha256=clHYYUKa8n4qef6PVlUV4mFHRRf6fnm9wEd2fu9oagA,2381
4
- logger_36/api/exception.py,sha256=QKIkNJA0N6FvVHLTApiH3ymhVQoSYU08t2RkyufQPIw,2291
5
4
  logger_36/api/gpu.py,sha256=BOumedCAPWvCo7J-KJ3XE-jr5S0KSmgcFv_S4QKRPO8,2252
6
5
  logger_36/api/memory.py,sha256=szJVk4UTXsbYv3B-W9LFttf1F3j86GXHsKgEUOsXKl4,2743
7
6
  logger_36/api/storage.py,sha256=t83D7Ge0ka7FCHUM8xchLsO_TMu0Bcc2IcBzw_gjkSA,2300
@@ -33,7 +32,6 @@ logger_36/constant/message.py,sha256=Ys_CAyhENlT8Z3rr-AxO4hjdl1jLsKzVSPQ8wqLOCPQ
33
32
  logger_36/constant/path.py,sha256=fKJn2vGj012BU5DFRetDFus_tKMty2q_WL0J2KrXdCo,2731
34
33
  logger_36/constant/record.py,sha256=9Q28lVH_s0og4v74delgwIPAJ9G28I5rBM-brXcoY80,2308
35
34
  logger_36/constant/system.py,sha256=G2mzBTxRXoJMxb53TnmBaceMJC_q3WonoCG7y6nC_R8,2430
36
- logger_36/extension/exception.py,sha256=CPie_jbp_cPhYln0dECFplykmS7pUaHqiiuQ4M5lvho,5416
37
35
  logger_36/extension/html_.py,sha256=J9EX8-Rotq9i8bZ9U-dIpXv5gKLLnLmWqdDy4XayT1Q,3868
38
36
  logger_36/extension/line.py,sha256=3MJ3B5PXJn18RHxBUcWnNBLEYzb7VTcEAufn7ULdYfY,3143
39
37
  logger_36/instance/logger.py,sha256=oTw5svRzKRJKvGrrZUtutJIOjp5UISft3fl0Ze7DOBE,2241
@@ -47,10 +45,10 @@ logger_36/task/measure/chronos.py,sha256=1kVhu6jZlNAtNWQQh8ZVuRwZIAC9gGz3_ul1tn0
47
45
  logger_36/task/measure/memory.py,sha256=OjU5EYFH8SnzlCQKAoiXvauUlwQYOrH34jFXTVYF0jE,2517
48
46
  logger_36/type/handler.py,sha256=2Q3crkhIzMLyuT7pBtpmouXgKWbULdsYw8vxQZBCT2g,6637
49
47
  logger_36/type/issue.py,sha256=2rGsFqaQJCbeml9xN08mN_nK79L8qscaS_0ws36Y0bI,3214
50
- logger_36/type/logger.py,sha256=X2qax6gPcT6lPsfNKM2aL5yHb_RUtIGJPWJ_GBxKSTU,25021
51
- logger_36/type/loggers.py,sha256=znqxWBnfQxvkg3VUfbTUvt3S6Kq0DAzWWepxQDt9suI,2871
48
+ logger_36/type/logger.py,sha256=86G05pa2_N9M1Vfck5NIBwn_LJhwf2W485Tc6sm5GSw,26256
49
+ logger_36/type/loggers.py,sha256=KLPoZ8UtQNhUw6MVu2pBcbSsIMKzgTaoxCulS1z2zPU,3748
52
50
  logger_36/type/message.py,sha256=zKME5p87ynsXte_b5usXV3VHaj34Uezs9Gg_WVWfaeY,3063
53
- logger_36-2025.15.dist-info/METADATA,sha256=wKz-PcmHE1ZvHLy4gj6pLm-2CcY_F2t8wE14ZbYGxsw,6506
54
- logger_36-2025.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
55
- logger_36-2025.15.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
56
- logger_36-2025.15.dist-info/RECORD,,
51
+ logger_36-2025.16.dist-info/METADATA,sha256=S9Dh7TabMHK2y5K4psh0RvRiDHfcJiTjjYZKBGnvcCA,6506
52
+ logger_36-2025.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
+ logger_36-2025.16.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
54
+ logger_36-2025.16.dist-info/RECORD,,
@@ -1,56 +0,0 @@
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
- from logger_36.extension.exception import ( # noqa
8
- OverrideExceptionFormat,
9
- ResetExceptionFormat,
10
- )
11
-
12
- """
13
- COPYRIGHT NOTICE
14
-
15
- This software is governed by the CeCILL license under French law and
16
- abiding by the rules of distribution of free software. You can use,
17
- modify and/ or redistribute the software under the terms of the CeCILL
18
- license as circulated by CEA, CNRS and INRIA at the following URL
19
- "http://www.cecill.info".
20
-
21
- As a counterpart to the access to the source code and rights to copy,
22
- modify and redistribute granted by the license, users are provided only
23
- with a limited warranty and the software's author, the holder of the
24
- economic rights, and the successive licensors have only limited
25
- liability.
26
-
27
- In this respect, the user's attention is drawn to the risks associated
28
- with loading, using, modifying and/or developing or reproducing the
29
- software by the user in light of its specific status of free software,
30
- that may mean that it is complicated to manipulate, and that also
31
- therefore means that it is reserved for developers and experienced
32
- professionals having in-depth computer knowledge. Users are therefore
33
- encouraged to load and test the software's suitability as regards their
34
- requirements in conditions enabling the security of their systems and/or
35
- data to be ensured and, more generally, to use and operate it in the
36
- same conditions as regards security.
37
-
38
- The fact that you are presently reading this means that you have had
39
- knowledge of the CeCILL license and that you accept its terms.
40
-
41
- SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
42
-
43
- This software is being developed by Eric Debreuve, a CNRS employee and
44
- member of team Morpheme.
45
- Team Morpheme is a joint team between Inria, CNRS, and UniCA.
46
- It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
47
- I3S, and Laboratory iBV.
48
-
49
- CNRS: https://www.cnrs.fr/index.php/en
50
- Inria: https://www.inria.fr/en/
51
- UniCA: https://univ-cotedazur.eu/
52
- Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
53
- I3S: https://www.i3s.unice.fr/en/
54
- iBV: http://ibv.unice.fr/
55
- Team Morpheme: https://team.inria.fr/morpheme/
56
- """
@@ -1,162 +0,0 @@
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 re as r
8
- import sys as s
9
- import tempfile as tmpf
10
- import textwrap as text
11
- import traceback as tcbk
12
- import types as t
13
- from pathlib import Path as path_t
14
-
15
- from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
16
- from logger_36.constant.path import USER_FOLDER
17
-
18
- _ORIGINAL_EXCEPTION_HANDLER = s.excepthook
19
- _INDENTATION = " "
20
-
21
- if RICH_IS_AVAILABLE:
22
- from rich import print as ShowErrorMessage # noqa
23
-
24
- TITLE_COLOR = "[red]"
25
- FUNCTION_COLOR = "[cyan]"
26
- REPORT_COLOR = "[red]"
27
- MONOCHROME = "[/]"
28
- OPTIONAL_NEWLINE = ""
29
- else:
30
- ShowErrorMessage = s.__stderr__.write
31
- TITLE_COLOR = WHERE_COLOR = REPORT_COLOR = MONOCHROME = ""
32
- OPTIONAL_NEWLINE = "\n"
33
-
34
-
35
- def OverrideExceptionFormat() -> None:
36
- """"""
37
- s.excepthook = _HandleException
38
-
39
-
40
- def ResetExceptionFormat() -> None:
41
- """"""
42
- s.excepthook = _ORIGINAL_EXCEPTION_HANDLER
43
-
44
-
45
- def _HandleException(
46
- stripe: type[Exception], exception: Exception, trace: t.TracebackType, /
47
- ) -> None:
48
- """"""
49
- while trace.tb_next is not None:
50
- trace = trace.tb_next
51
- frame = trace.tb_frame
52
- code = frame.f_code
53
- module = path_t(code.co_filename)
54
- function = code.co_name
55
- line_number = frame.f_lineno
56
- line_content = module.read_text().splitlines()[line_number - 1].strip()
57
-
58
- # Format module.
59
- if module.is_relative_to(USER_FOLDER):
60
- module = path_t("~") / module.relative_to(USER_FOLDER)
61
-
62
- # Format line content.
63
- if line_content.startswith("raise "):
64
- # Do not display code of explicit exception raising.
65
- line_content = None
66
-
67
- # Find variables appearing in the line.
68
- if line_content is None:
69
- line_content = variables = ""
70
- else:
71
- all_variables = frame.f_locals
72
- found_names = []
73
- for match in r.finditer(r"[^\d\W]\w*", line_content):
74
- name = match.group()
75
- if name in all_variables:
76
- found_names.append(name)
77
- if found_names.__len__() > 0:
78
- longest = max(map(len, found_names))
79
- variables = map(
80
- lambda _: f"{_:{longest}} = {all_variables[_]}", sorted(found_names)
81
- )
82
- variables = (
83
- 2 * _INDENTATION + f"\n{2 * _INDENTATION}".join(variables) + "\n"
84
- )
85
- else:
86
- variables = ""
87
-
88
- line_content = f"{_INDENTATION}{line_content}\n"
89
-
90
- # Format message.
91
- message = str(exception).strip()
92
- if message.__len__() > 0:
93
- if "\n" in message:
94
- message = text.indent(message, 2 * _INDENTATION)[
95
- (2 * _INDENTATION.__len__()) :
96
- ]
97
- message = f"{_INDENTATION}{message[0].title()}{message[1:]}\n"
98
-
99
- document = tmpf.NamedTemporaryFile(delete=False)
100
-
101
- ShowErrorMessage(
102
- f"{TITLE_COLOR}{stripe.__name__}{MONOCHROME}\n"
103
- f"{_INDENTATION}{module}:{FUNCTION_COLOR}{function}{MONOCHROME}@{line_number}\n"
104
- f"{line_content}"
105
- f"{variables}"
106
- f"{message}"
107
- f"{_INDENTATION}{REPORT_COLOR}Full report at: file://{document.name}"
108
- f"{MONOCHROME}{OPTIONAL_NEWLINE}"
109
- )
110
-
111
- lines = tcbk.format_exception(exception)
112
- message = "".join(lines)
113
-
114
- document.write(message.encode())
115
- document.close()
116
-
117
-
118
- """
119
- COPYRIGHT NOTICE
120
-
121
- This software is governed by the CeCILL license under French law and
122
- abiding by the rules of distribution of free software. You can use,
123
- modify and/ or redistribute the software under the terms of the CeCILL
124
- license as circulated by CEA, CNRS and INRIA at the following URL
125
- "http://www.cecill.info".
126
-
127
- As a counterpart to the access to the source code and rights to copy,
128
- modify and redistribute granted by the license, users are provided only
129
- with a limited warranty and the software's author, the holder of the
130
- economic rights, and the successive licensors have only limited
131
- liability.
132
-
133
- In this respect, the user's attention is drawn to the risks associated
134
- with loading, using, modifying and/or developing or reproducing the
135
- software by the user in light of its specific status of free software,
136
- that may mean that it is complicated to manipulate, and that also
137
- therefore means that it is reserved for developers and experienced
138
- professionals having in-depth computer knowledge. Users are therefore
139
- encouraged to load and test the software's suitability as regards their
140
- requirements in conditions enabling the security of their systems and/or
141
- data to be ensured and, more generally, to use and operate it in the
142
- same conditions as regards security.
143
-
144
- The fact that you are presently reading this means that you have had
145
- knowledge of the CeCILL license and that you accept its terms.
146
-
147
- SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
148
-
149
- This software is being developed by Eric Debreuve, a CNRS employee and
150
- member of team Morpheme.
151
- Team Morpheme is a joint team between Inria, CNRS, and UniCA.
152
- It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
153
- I3S, and Laboratory iBV.
154
-
155
- CNRS: https://www.cnrs.fr/index.php/en
156
- Inria: https://www.inria.fr/en/
157
- UniCA: https://univ-cotedazur.eu/
158
- Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
159
- I3S: https://www.i3s.unice.fr/en/
160
- iBV: http://ibv.unice.fr/
161
- Team Morpheme: https://team.inria.fr/morpheme/
162
- """