logger-36 2025.16__tar.gz → 2025.17__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 (64) hide show
  1. {logger_36-2025.16 → logger_36-2025.17}/PKG-INFO +1 -1
  2. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/handler/console.py +1 -2
  3. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/handler/console_rich.py +2 -14
  4. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/handler/file.py +1 -4
  5. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/handler/generic.py +2 -14
  6. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/logger/memory.py +7 -5
  7. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/handler.py +0 -2
  8. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/path.py +2 -2
  9. logger_36-2025.17/package/logger_36/constant/record.py +54 -0
  10. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/type/handler.py +6 -20
  11. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/type/logger.py +30 -32
  12. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/version.py +1 -1
  13. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36.egg-info/PKG-INFO +1 -1
  14. logger_36-2025.16/package/logger_36/constant/record.py +0 -55
  15. {logger_36-2025.16 → logger_36-2025.17}/MANIFEST.in +0 -0
  16. {logger_36-2025.16 → logger_36-2025.17}/README-COPYRIGHT-utf8.txt +0 -0
  17. {logger_36-2025.16 → logger_36-2025.17}/README-LICENCE-utf8.txt +0 -0
  18. {logger_36-2025.16 → logger_36-2025.17}/README.rst +0 -0
  19. {logger_36-2025.16 → logger_36-2025.17}/documentation/wiki/description.asciidoc +0 -0
  20. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/__init__.py +0 -0
  21. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/content.py +0 -0
  22. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/gpu.py +0 -0
  23. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/memory.py +0 -0
  24. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/storage.py +0 -0
  25. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/system.py +0 -0
  26. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/time.py +0 -0
  27. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/api/type.py +0 -0
  28. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/config/console_rich.py +0 -0
  29. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/config/optional.py +0 -0
  30. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/logger/chronos.py +0 -0
  31. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/logger/gpu.py +0 -0
  32. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/catalog/logger/system.py +0 -0
  33. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/config/issue.py +0 -0
  34. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/config/memory.py +0 -0
  35. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/config/message.py +0 -0
  36. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/config/system.py +0 -0
  37. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/error.py +0 -0
  38. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/generic.py +0 -0
  39. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/html.py +0 -0
  40. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/issue.py +0 -0
  41. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/logger.py +0 -0
  42. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/memory.py +0 -0
  43. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/message.py +0 -0
  44. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/constant/system.py +0 -0
  45. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/extension/html_.py +0 -0
  46. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/extension/line.py +0 -0
  47. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/instance/logger.py +0 -0
  48. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/instance/loggers.py +0 -0
  49. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/format/memory.py +0 -0
  50. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/format/message.py +0 -0
  51. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/format/rule.py +0 -0
  52. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/inspection.py +0 -0
  53. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/measure/chronos.py +0 -0
  54. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/measure/memory.py +0 -0
  55. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/task/storage.py +0 -0
  56. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/type/issue.py +0 -0
  57. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/type/loggers.py +0 -0
  58. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36/type/message.py +0 -0
  59. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36.egg-info/SOURCES.txt +0 -0
  60. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36.egg-info/dependency_links.txt +0 -0
  61. {logger_36-2025.16 → logger_36-2025.17}/package/logger_36.egg-info/top_level.txt +0 -0
  62. {logger_36-2025.16 → logger_36-2025.17}/pyproject.toml +0 -0
  63. {logger_36-2025.16 → logger_36-2025.17}/setup.cfg +0 -0
  64. {logger_36-2025.16 → logger_36-2025.17}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logger-36
3
- Version: 2025.16
3
+ Version: 2025.17
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
@@ -21,14 +21,13 @@ class console_handler_t(base_t):
21
21
  /,
22
22
  *,
23
23
  name: str | None = None,
24
- should_store_memory_usage: bool = False,
25
24
  message_width: int = -1,
26
25
  level: int = l.NOTSET,
27
26
  formatter: l.Formatter | None = None,
28
27
  **_,
29
28
  ) -> h.Self:
30
29
  """"""
31
- return cls(name, should_store_memory_usage, message_width, level, formatter)
30
+ return cls(name, message_width, level, formatter)
32
31
 
33
32
  def emit(self, record: l.LogRecord, /) -> None:
34
33
  """"""
@@ -55,7 +55,6 @@ class console_rich_handler_t(base_t):
55
55
  def __init__(
56
56
  self,
57
57
  name: str | None,
58
- should_store_memory_usage: bool,
59
58
  message_width: int,
60
59
  level: int,
61
60
  formatter: l.Formatter | None,
@@ -67,15 +66,7 @@ class console_rich_handler_t(base_t):
67
66
 
68
67
  assert alternating_logs in (0, 1, 2)
69
68
 
70
- base_t.__init__(
71
- self,
72
- name,
73
- should_store_memory_usage,
74
- message_width,
75
- level,
76
- formatter,
77
- kwargs,
78
- )
69
+ base_t.__init__(self, name, message_width, level, formatter, kwargs)
79
70
 
80
71
  self.console = None # console_t | None.
81
72
  self.alternating_logs = alternating_logs
@@ -105,16 +96,13 @@ class console_rich_handler_t(base_t):
105
96
  /,
106
97
  *,
107
98
  name: str | None = None,
108
- should_store_memory_usage: bool = False,
109
99
  message_width: int = -1,
110
100
  level: int = l.NOTSET,
111
101
  formatter: l.Formatter | None = None,
112
102
  **kwargs,
113
103
  ) -> h.Self:
114
104
  """"""
115
- return cls(
116
- name, should_store_memory_usage, message_width, level, formatter, kwargs
117
- )
105
+ return cls(name, message_width, level, formatter, kwargs)
118
106
 
119
107
  def emit(self, record: l.LogRecord, /) -> None:
120
108
  """"""
@@ -21,7 +21,6 @@ class file_handler_t(base_t):
21
21
  /,
22
22
  *,
23
23
  name: str | None = None,
24
- should_store_memory_usage: bool = False,
25
24
  message_width: int = -1,
26
25
  level: int = l.NOTSET,
27
26
  formatter: l.Formatter | None = None,
@@ -29,9 +28,7 @@ class file_handler_t(base_t):
29
28
  **_,
30
29
  ) -> h.Self:
31
30
  """"""
32
- return cls(
33
- name, should_store_memory_usage, message_width, level, formatter, path
34
- )
31
+ return cls(name, message_width, level, formatter, path)
35
32
 
36
33
  def emit(self, record: l.LogRecord, /) -> None:
37
34
  """"""
@@ -56,7 +56,6 @@ class generic_handler_t(base_t):
56
56
  def __init__(
57
57
  self,
58
58
  name: str | None,
59
- should_store_memory_usage: bool,
60
59
  message_width: int,
61
60
  level: int,
62
61
  formatter: l.Formatter | None,
@@ -69,15 +68,7 @@ class generic_handler_t(base_t):
69
68
 
70
69
  assert alternating_logs in (0, 1, 2)
71
70
 
72
- base_t.__init__(
73
- self,
74
- name,
75
- should_store_memory_usage,
76
- message_width,
77
- level,
78
- formatter,
79
- kwargs,
80
- )
71
+ base_t.__init__(self, name, message_width, level, formatter, kwargs)
81
72
 
82
73
  self.LogAsIs = LogAsIs
83
74
  self.DisplayRule = None # DisplayRule_p | None.
@@ -105,16 +96,13 @@ class generic_handler_t(base_t):
105
96
  /,
106
97
  *,
107
98
  name: str | None = None,
108
- should_store_memory_usage: bool = False,
109
99
  message_width: int = -1,
110
100
  level: int = l.NOTSET,
111
101
  formatter: l.Formatter | None = None,
112
102
  **kwargs,
113
103
  ) -> h.Self:
114
104
  """"""
115
- return cls(
116
- name, should_store_memory_usage, message_width, level, formatter, kwargs
117
- )
105
+ return cls(name, message_width, level, formatter, kwargs)
118
106
 
119
107
  def emit(self, record: l.LogRecord, /) -> None:
120
108
  """"""
@@ -21,7 +21,7 @@ def LogMemoryUsages(
21
21
  logger: logger_t = L,
22
22
  ) -> None:
23
23
  """"""
24
- if not logger.any_handler_stores_memory:
24
+ if (not hasattr(logger, "memory_usages")) or (logger.memory_usages.__len__() == 0):
25
25
  return
26
26
 
27
27
  where_s, usages = zip(*logger.memory_usages)
@@ -76,10 +76,12 @@ def LogMaximumMemoryUsage(
76
76
  """
77
77
  unit: b or None=bytes, k=kilo, m=mega, g=giga, a=auto
78
78
  """
79
- if logger.any_handler_stores_memory:
80
- where, max_usage = logger.max_memory_usage_full
81
- value, unit = FormattedUsage(max_usage, unit=unit, decimals=decimals)
82
- logger.info(f"Max. Memory Usage: {value}{unit} near {where}")
79
+ if (not hasattr(logger, "memory_usages")) or (logger.memory_usages.__len__() == 0):
80
+ return
81
+
82
+ where, max_usage = logger.max_memory_usage_full
83
+ value, unit = FormattedUsage(max_usage, unit=unit, decimals=decimals)
84
+ logger.info(f"Max. Memory Usage: {value}{unit} near {where}")
83
85
 
84
86
 
85
87
  """
@@ -9,8 +9,6 @@ import typing as h
9
9
  handler_codes_h = h.Literal["g", "c", "f", "a"] # g=generic, c=console, f=file, a=all.
10
10
  HANDLER_KINDS: tuple[str, ...] = h.get_args(handler_codes_h)
11
11
 
12
- ANONYMOUS = "<Anonymous>"
13
-
14
12
  """
15
13
  COPYRIGHT NOTICE
16
14
 
@@ -4,13 +4,13 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
4
4
  SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
- import inspect as nspt
7
+ import inspect as e
8
8
  import tempfile as tmps
9
9
  from pathlib import Path as path_t
10
10
 
11
11
  USER_FOLDER = path_t.home()
12
12
 
13
- frame = nspt.stack()[-1]
13
+ frame = e.stack(context=0)[-1] # -1=root caller.
14
14
  if path_t(frame.filename).exists():
15
15
  PROJECT_FILE = path_t(frame.filename)
16
16
  if PROJECT_FILE.is_relative_to(USER_FOLDER):
@@ -0,0 +1,54 @@
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
+ SHOW_W_RULE_ATTR = "should_show_w_rule"
8
+ SHOW_WHERE_ATTR = "should_show_where"
9
+
10
+ """
11
+ COPYRIGHT NOTICE
12
+
13
+ This software is governed by the CeCILL license under French law and
14
+ abiding by the rules of distribution of free software. You can use,
15
+ modify and/ or redistribute the software under the terms of the CeCILL
16
+ license as circulated by CEA, CNRS and INRIA at the following URL
17
+ "http://www.cecill.info".
18
+
19
+ As a counterpart to the access to the source code and rights to copy,
20
+ modify and redistribute granted by the license, users are provided only
21
+ with a limited warranty and the software's author, the holder of the
22
+ economic rights, and the successive licensors have only limited
23
+ liability.
24
+
25
+ In this respect, the user's attention is drawn to the risks associated
26
+ with loading, using, modifying and/or developing or reproducing the
27
+ software by the user in light of its specific status of free software,
28
+ that may mean that it is complicated to manipulate, and that also
29
+ therefore means that it is reserved for developers and experienced
30
+ professionals having in-depth computer knowledge. Users are therefore
31
+ encouraged to load and test the software's suitability as regards their
32
+ requirements in conditions enabling the security of their systems and/or
33
+ data to be ensured and, more generally, to use and operate it in the
34
+ same conditions as regards security.
35
+
36
+ The fact that you are presently reading this means that you have had
37
+ knowledge of the CeCILL license and that you accept its terms.
38
+
39
+ SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
40
+
41
+ This software is being developed by Eric Debreuve, a CNRS employee and
42
+ member of team Morpheme.
43
+ Team Morpheme is a joint team between Inria, CNRS, and UniCA.
44
+ It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
45
+ I3S, and Laboratory iBV.
46
+
47
+ CNRS: https://www.cnrs.fr/index.php/en
48
+ Inria: https://www.inria.fr/en/
49
+ UniCA: https://univ-cotedazur.eu/
50
+ Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
51
+ I3S: https://www.i3s.unice.fr/en/
52
+ iBV: http://ibv.unice.fr/
53
+ Team Morpheme: https://team.inria.fr/morpheme/
54
+ """
@@ -10,26 +10,22 @@ import typing as h
10
10
  from pathlib import Path as path_t
11
11
 
12
12
  from logger_36.config.message import FALLBACK_MESSAGE_WIDTH
13
- from logger_36.constant.error import MEMORY_MEASURE_ERROR
14
13
  from logger_36.constant.handler import HANDLER_KINDS
15
14
  from logger_36.task.format.message import MessageFromRecord, MessageWithActualExpected
16
15
  from logger_36.task.format.rule import RuleAsText
17
16
  from logger_36.task.measure.chronos import TimeStamp
18
- from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
19
17
  from logger_36.type.message import MessageFromRecord_h, RuleWithText_h
20
18
 
21
- _MEMORY_MEASURE_ERROR = MEMORY_MEASURE_ERROR
22
-
23
19
 
24
20
  class _base_t:
25
21
  kind: h.ClassVar[str] = "" # See logger_36.constant.handler.handler_codes_h.
26
22
 
27
- def __init__(
28
- self, name: str | None, should_store_memory_usage: bool, message_width: int
29
- ) -> None:
23
+ def __init__(self, name: str | None, message_width: int) -> None:
30
24
  """"""
25
+ if name is None:
26
+ name = f"{type(self).__name__}:{id(self)}"
27
+
31
28
  self.name = name
32
- self.should_store_memory_usage = should_store_memory_usage
33
29
  self.message_width = message_width
34
30
  #
35
31
  self.MessageFromRecord: MessageFromRecord_h | None = None
@@ -38,8 +34,6 @@ class _base_t:
38
34
 
39
35
  def __post_init__(self) -> None:
40
36
  """"""
41
- global _MEMORY_MEASURE_ERROR
42
-
43
37
  if self.name in HANDLER_KINDS:
44
38
  raise ValueError(
45
39
  MessageWithActualExpected(
@@ -52,12 +46,6 @@ class _base_t:
52
46
  if self.name is None:
53
47
  self.name = TimeStamp()
54
48
 
55
- if self.should_store_memory_usage and not CanCheckMemoryUsage():
56
- self.should_store_memory_usage = False
57
- if _MEMORY_MEASURE_ERROR is not None:
58
- s.__stderr__.write(_MEMORY_MEASURE_ERROR + "\n")
59
- _MEMORY_MEASURE_ERROR = None
60
-
61
49
  if 0 < self.message_width < FALLBACK_MESSAGE_WIDTH:
62
50
  self.message_width = FALLBACK_MESSAGE_WIDTH
63
51
 
@@ -84,7 +72,6 @@ class handler_t(l.Handler, _base_t):
84
72
  def __init__(
85
73
  self,
86
74
  name: str | None,
87
- should_store_memory_usage: bool,
88
75
  message_width: int,
89
76
  level: int,
90
77
  formatter: l.Formatter | None,
@@ -92,7 +79,7 @@ class handler_t(l.Handler, _base_t):
92
79
  ) -> None:
93
80
  """"""
94
81
  l.Handler.__init__(self)
95
- _base_t.__init__(self, name, should_store_memory_usage, message_width)
82
+ _base_t.__init__(self, name, message_width)
96
83
  __post_init__(self, level, formatter)
97
84
 
98
85
 
@@ -100,7 +87,6 @@ class file_handler_t(l.FileHandler, _base_t):
100
87
  def __init__(
101
88
  self,
102
89
  name: str | None,
103
- should_store_memory_usage: bool,
104
90
  message_width: int,
105
91
  level: int,
106
92
  formatter: l.Formatter | None,
@@ -116,7 +102,7 @@ class file_handler_t(l.FileHandler, _base_t):
116
102
  raise ValueError(f"File or folder already exists: {path}.")
117
103
 
118
104
  l.FileHandler.__init__(self, path)
119
- _base_t.__init__(self, name, should_store_memory_usage, message_width)
105
+ _base_t.__init__(self, name, message_width)
120
106
  __post_init__(self, level, formatter)
121
107
 
122
108
 
@@ -5,6 +5,7 @@ SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
7
  import dataclasses as d
8
+ import inspect as e
8
9
  import logging as l
9
10
  import sys as s
10
11
  import textwrap as text
@@ -28,8 +29,9 @@ from logger_36.config.message import (
28
29
  LONG_ENOUGH,
29
30
  TIME_FORMAT,
30
31
  )
32
+ from logger_36.constant.error import MEMORY_MEASURE_ERROR
31
33
  from logger_36.constant.generic import NOT_PASSED
32
- from logger_36.constant.handler import ANONYMOUS, HANDLER_KINDS, handler_codes_h
34
+ from logger_36.constant.handler import HANDLER_KINDS, handler_codes_h
33
35
  from logger_36.constant.issue import ISSUE_LEVEL_SEPARATOR, ORDER, order_h
34
36
  from logger_36.constant.logger import (
35
37
  LOGGER_NAME,
@@ -39,14 +41,11 @@ from logger_36.constant.logger import (
39
41
  from logger_36.constant.memory import UNKNOWN_MEMORY_USAGE
40
42
  from logger_36.constant.message import LINE_INDENT, TIME_LENGTH_m_1, expected_op_h
41
43
  from logger_36.constant.path import PROJECT_FILE_RELATIVE
42
- from logger_36.constant.record import (
43
- HIDE_WHERE_ATTR,
44
- SHOW_W_RULE_ATTR,
45
- STORE_MEMORY_ATTR,
46
- )
44
+ from logger_36.constant.record import SHOW_W_RULE_ATTR, SHOW_WHERE_ATTR
47
45
  from logger_36.task.format.message import MessageFromRecord, MessageWithActualExpected
48
46
  from logger_36.task.format.rule import RuleAsText
49
47
  from logger_36.task.measure.chronos import ElapsedTime
48
+ from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
50
49
  from logger_36.task.measure.memory import CurrentUsage as CurrentMemoryUsage
51
50
  from logger_36.type.handler import any_handler_t as base_handler_t
52
51
  from logger_36.type.issue import NewIssue, issue_t
@@ -66,6 +65,7 @@ logger_handle_h = logger_handle_raw_h | logger_handle_with_self_h
66
65
 
67
66
  _DATE_TIME_ORIGIN = date_time_t.fromtimestamp(1970, None)
68
67
  _DATE_ORIGIN = _DATE_TIME_ORIGIN.date()
68
+ _MEMORY_MEASURE_ERROR = MEMORY_MEASURE_ERROR
69
69
 
70
70
 
71
71
  @d.dataclass(slots=True, repr=False, eq=False)
@@ -85,6 +85,7 @@ class logger_t(base_t):
85
85
  """
86
86
 
87
87
  should_record_messages: bool = False
88
+ should_watch_memory_usage: bool = False
88
89
  exit_on_error: bool = False # Implies exit_on_critical.
89
90
  exit_on_critical: bool = False
90
91
 
@@ -93,7 +94,6 @@ class logger_t(base_t):
93
94
 
94
95
  last_message_now: date_time_t = d.field(init=False, default=_DATE_TIME_ORIGIN)
95
96
  last_message_date: date_t = d.field(init=False, default=_DATE_ORIGIN)
96
- any_handler_stores_memory: bool = d.field(init=False, default=False)
97
97
  memory_usages: list[tuple[str, int]] = d.field(init=False, default_factory=list)
98
98
  context_levels: list[str] = d.field(init=False, default_factory=list)
99
99
  staged_issues: list[issue_t] = d.field(init=False, default_factory=list)
@@ -159,6 +159,8 @@ class logger_t(base_t):
159
159
  activate_exc_interceptions: bool,
160
160
  ) -> None:
161
161
  """"""
162
+ global _MEMORY_MEASURE_ERROR
163
+
162
164
  base_t.__init__(self, name_)
163
165
  self.setLevel(level_)
164
166
  self.propagate = False # Part of base_t.
@@ -178,6 +180,12 @@ class logger_t(base_t):
178
180
  if self.exit_on_error:
179
181
  self.exit_on_critical = True
180
182
 
183
+ if self.should_watch_memory_usage and not CanCheckMemoryUsage():
184
+ self.should_watch_memory_usage = False
185
+ if _MEMORY_MEASURE_ERROR is not None:
186
+ s.__stderr__.write(_MEMORY_MEASURE_ERROR + "\n")
187
+ _MEMORY_MEASURE_ERROR = None
188
+
181
189
  def handle(self, record: l.LogRecord, /) -> None:
182
190
  """"""
183
191
  elapsed_time, now = ElapsedTime(should_return_now=True)
@@ -224,12 +232,8 @@ class logger_t(base_t):
224
232
  self.last_message_now = now
225
233
 
226
234
  # Where.
227
- # Memory usage is also stored if there are no handlers yet, just in case.
228
- should_store_where = self.any_handler_stores_memory or not self.hasHandlers()
229
- should_show_where = (record.levelno != l.INFO) and not hasattr(
230
- record, HIDE_WHERE_ATTR
231
- )
232
- if should_store_where or should_show_where:
235
+ should_show_where = getattr(record, SHOW_WHERE_ATTR, record.levelno != l.INFO)
236
+ if should_show_where or self.should_watch_memory_usage:
233
237
  module = path_t(record.pathname)
234
238
  for path in s.path:
235
239
  if module.is_relative_to(path):
@@ -269,7 +273,7 @@ class logger_t(base_t):
269
273
 
270
274
  self.events[record.levelno] += 1
271
275
 
272
- if should_store_where:
276
+ if self.should_watch_memory_usage:
273
277
  self.memory_usages.append((where, CurrentMemoryUsage()))
274
278
 
275
279
  def SetLevel(self, level: int, /, *, which: handler_codes_h | str = "a") -> None:
@@ -417,7 +421,6 @@ class logger_t(base_t):
417
421
  *,
418
422
  name: str | None = None,
419
423
  level: int = l.INFO,
420
- should_store_memory_usage: bool = False,
421
424
  message_width: int = -1,
422
425
  formatter: l.Formatter | None = None,
423
426
  should_still_hold_messages: bool = False,
@@ -429,9 +432,9 @@ class logger_t(base_t):
429
432
  self._should_activate_log_interceptions = False
430
433
 
431
434
  self._should_hold_messages = should_still_hold_messages
435
+
432
436
  handler = handler_t.New(
433
437
  name=name,
434
- should_store_memory_usage=should_store_memory_usage,
435
438
  message_width=message_width,
436
439
  level=level,
437
440
  formatter=formatter,
@@ -439,31 +442,26 @@ class logger_t(base_t):
439
442
  )
440
443
  base_t.addHandler(self, handler)
441
444
 
442
- extension = getattr(handler, "extension", None)
443
- if extension is None:
444
- name = handler.name
445
- if (name is None) or (name.__len__() == 0):
446
- name = ANONYMOUS
447
- else:
448
- name = getattr(extension, "name", ANONYMOUS)
449
- if getattr(extension, STORE_MEMORY_ATTR, False):
450
- self.any_handler_stores_memory = True
451
-
452
445
  path = getattr(handler, "baseFilename", "")
453
446
  if isinstance(path, path_t) or (path.__len__() > 0):
454
447
  path = f"\nPath: {path}"
455
-
456
448
  self.info(
457
- f'New handler "{name}" of type "{type(handler).__name__}" and '
449
+ f'New handler "{handler.name}" of type "{type(handler).__name__}" and '
458
450
  f"level {handler.level}={l.getLevelName(handler.level)}{path}"
459
451
  )
460
452
 
461
453
  def __call__(self, *args, **kwargs) -> None:
462
454
  """
463
- For a print-like calling.
455
+ For a print-like calling for print-based debugging.
464
456
  """
457
+ frame = e.stack(context=0)[1][0] # 1=caller.
458
+ details = e.getframeinfo(frame, context=0)
459
+ path = path_t(details.filename).relative_to(path_t.home())
460
+ where = f"{str(path)[:-3]}.{details.function}.{details.lineno}"
461
+
465
462
  separator = kwargs.get("separator", " ")
466
- self.info(separator.join(map(str, args)))
463
+
464
+ self.info(where + "\n" + separator.join(map(str, args)))
467
465
 
468
466
  def Log(
469
467
  self,
@@ -510,7 +508,7 @@ class logger_t(base_t):
510
508
  # - Why adding exception name here and not when removing caller?
511
509
  formatted = "".join(lines)
512
510
  message = f"Exception of type {type(exception).__name__}\n----\n{formatted}"
513
- self.log(level, message, extra={HIDE_WHERE_ATTR: None})
511
+ self.log(level, message, extra={SHOW_WHERE_ATTR: False})
514
512
 
515
513
  def LogAsIs(self, message: str, /, *, indented: bool = False) -> None:
516
514
  """"""
@@ -624,7 +622,7 @@ class logger_t(base_t):
624
622
  formatted = "\n".join(lines)
625
623
  """
626
624
 
627
- hide_where = {HIDE_WHERE_ATTR: None}
625
+ hide_where = {SHOW_WHERE_ATTR: False}
628
626
  if unified:
629
627
  level, _ = issues[0].split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
630
628
  wo_level = []
@@ -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.16"
7
+ __version__ = "2025.17"
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.16
3
+ Version: 2025.17
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,55 +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
- SHOW_W_RULE_ATTR = "should_show_w_rule"
8
- STORE_MEMORY_ATTR = "should_store_memory_usage"
9
- HIDE_WHERE_ATTR = "should_hide_where"
10
-
11
- """
12
- COPYRIGHT NOTICE
13
-
14
- This software is governed by the CeCILL license under French law and
15
- abiding by the rules of distribution of free software. You can use,
16
- modify and/ or redistribute the software under the terms of the CeCILL
17
- license as circulated by CEA, CNRS and INRIA at the following URL
18
- "http://www.cecill.info".
19
-
20
- As a counterpart to the access to the source code and rights to copy,
21
- modify and redistribute granted by the license, users are provided only
22
- with a limited warranty and the software's author, the holder of the
23
- economic rights, and the successive licensors have only limited
24
- liability.
25
-
26
- In this respect, the user's attention is drawn to the risks associated
27
- with loading, using, modifying and/or developing or reproducing the
28
- software by the user in light of its specific status of free software,
29
- that may mean that it is complicated to manipulate, and that also
30
- therefore means that it is reserved for developers and experienced
31
- professionals having in-depth computer knowledge. Users are therefore
32
- encouraged to load and test the software's suitability as regards their
33
- requirements in conditions enabling the security of their systems and/or
34
- data to be ensured and, more generally, to use and operate it in the
35
- same conditions as regards security.
36
-
37
- The fact that you are presently reading this means that you have had
38
- knowledge of the CeCILL license and that you accept its terms.
39
-
40
- SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
41
-
42
- This software is being developed by Eric Debreuve, a CNRS employee and
43
- member of team Morpheme.
44
- Team Morpheme is a joint team between Inria, CNRS, and UniCA.
45
- It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
46
- I3S, and Laboratory iBV.
47
-
48
- CNRS: https://www.cnrs.fr/index.php/en
49
- Inria: https://www.inria.fr/en/
50
- UniCA: https://univ-cotedazur.eu/
51
- Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
52
- I3S: https://www.i3s.unice.fr/en/
53
- iBV: http://ibv.unice.fr/
54
- Team Morpheme: https://team.inria.fr/morpheme/
55
- """
File without changes
File without changes
File without changes
File without changes
File without changes