logger-36 2024.27__py3-none-any.whl → 2024.29__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/handler.py CHANGED
@@ -6,12 +6,11 @@ SEE COPYRIGHT NOTICE BELOW
6
6
 
7
7
  import logging as lggg
8
8
  import sys as sstm
9
- import typing as h
10
9
  from pathlib import Path as path_t
11
10
 
12
11
  from logger_36.catalog.handler.console import console_handler_t
13
12
  from logger_36.catalog.handler.file import file_handler_t
14
- from logger_36.catalog.handler.generic import generic_handler_t
13
+ from logger_36.catalog.handler.generic import generic_handler_t, show_message_p
15
14
  from logger_36.constant.error import MISSING_RICH_ERROR
16
15
  from logger_36.instance.logger import LOGGER
17
16
 
@@ -28,14 +27,13 @@ except ModuleNotFoundError:
28
27
 
29
28
 
30
29
  def AddGenericHandler(
31
- ShowMessage: h.Callable[[str], None],
30
+ ShowMessage: show_message_p,
32
31
  /,
33
32
  *,
34
33
  logger: lggg.Logger | None = None,
35
34
  name: str | None = None,
36
35
  level: int = lggg.INFO,
37
- show_where: bool = True,
38
- show_memory_usage: bool = False,
36
+ should_store_memory_usage: bool = False,
39
37
  message_width: int = -1,
40
38
  formatter: lggg.Formatter | None = None,
41
39
  supports_html: bool = False,
@@ -51,8 +49,7 @@ def AddGenericHandler(
51
49
  handler = generic_handler_t(
52
50
  name=name,
53
51
  level=level,
54
- show_where=show_where,
55
- show_memory_usage=show_memory_usage,
52
+ should_store_memory_usage=should_store_memory_usage,
56
53
  message_width=message_width,
57
54
  formatter=formatter,
58
55
  supports_html=supports_html,
@@ -69,8 +66,7 @@ def AddConsoleHandler(
69
66
  logger: lggg.Logger | None = None,
70
67
  name: str | None = None,
71
68
  level: int = lggg.INFO,
72
- show_where: bool = True,
73
- show_memory_usage: bool = False,
69
+ should_store_memory_usage: bool = False,
74
70
  message_width: int = -1,
75
71
  formatter: lggg.Formatter | None = None,
76
72
  should_hold_messages: bool = False,
@@ -82,8 +78,7 @@ def AddConsoleHandler(
82
78
  handler = console_handler_t(
83
79
  name=name,
84
80
  level=level,
85
- show_where=show_where,
86
- show_memory_usage=show_memory_usage,
81
+ should_store_memory_usage=should_store_memory_usage,
87
82
  message_width=message_width,
88
83
  formatter=formatter,
89
84
  )
@@ -95,8 +90,7 @@ def AddRichConsoleHandler(
95
90
  logger: lggg.Logger | None = None,
96
91
  name: str | None = None,
97
92
  level: int = lggg.INFO,
98
- show_where: bool = True,
99
- show_memory_usage: bool = False,
93
+ should_store_memory_usage: bool = False,
100
94
  message_width: int = -1,
101
95
  formatter: lggg.Formatter | None = None,
102
96
  alternating_lines: int = 2,
@@ -126,8 +120,7 @@ def AddRichConsoleHandler(
126
120
  handler = console_rich_handler_t(
127
121
  name=name,
128
122
  level=level,
129
- show_where=show_where,
130
- show_memory_usage=show_memory_usage,
123
+ should_store_memory_usage=should_store_memory_usage,
131
124
  message_width=message_width,
132
125
  formatter=formatter,
133
126
  **additional_s,
@@ -142,8 +135,7 @@ def AddFileHandler(
142
135
  logger: lggg.Logger | None = None,
143
136
  name: str | None = None,
144
137
  level: int = lggg.INFO,
145
- show_where: bool = True,
146
- show_memory_usage: bool = False,
138
+ should_store_memory_usage: bool = False,
147
139
  message_width: int = -1,
148
140
  formatter: lggg.Formatter | None = None,
149
141
  should_hold_messages: bool = False,
@@ -160,8 +152,7 @@ def AddFileHandler(
160
152
  handler = file_handler_t(
161
153
  name=name,
162
154
  level=level,
163
- show_where=show_where,
164
- show_memory_usage=show_memory_usage,
155
+ should_store_memory_usage=should_store_memory_usage,
165
156
  message_width=message_width,
166
157
  formatter=formatter,
167
158
  path=path,
@@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
7
  from logger_36.constant.memory import STORAGE_UNITS, storage_units_h
8
- from logger_36.task.format.message import FormattedMessage
8
+ from logger_36.task.format.message import MessageWithActualExpected
9
9
 
10
10
  _KILO_UNIT = 1000.0
11
11
  _MEGA_UNIT = _KILO_UNIT * 1000.0
@@ -41,7 +41,7 @@ def FormattedUsage(
41
41
  value, unit = FormattedUsageWithAutoUnit(usage, decimals)
42
42
  else:
43
43
  raise ValueError(
44
- FormattedMessage(
44
+ MessageWithActualExpected(
45
45
  "Invalid unit", actual=unit, expected=str(STORAGE_UNITS)[1:-1]
46
46
  )
47
47
  )
@@ -7,35 +7,11 @@ SEE COPYRIGHT NOTICE BELOW
7
7
  import difflib as diff
8
8
  import typing as h
9
9
 
10
- from logger_36.config.message import (
11
- ELAPSED_TIME_FORMAT,
12
- LEVEL_CLOSING,
13
- LEVEL_OPENING,
14
- MEMORY_FORMAT,
15
- MESSAGE_MARKER,
16
- )
17
10
  from logger_36.constant.generic import NOT_PASSED
18
11
  from logger_36.constant.message import expected_op_h
19
12
 
20
13
 
21
- def MessageFormat(with_where: bool, with_memory_usage: bool, /) -> str:
22
- """"""
23
- output = [
24
- f"%(asctime)s"
25
- f"{LEVEL_OPENING}%(level_first_letter)s{LEVEL_CLOSING}\t"
26
- f"{MESSAGE_MARKER}%(message)s"
27
- ]
28
-
29
- if with_where:
30
- output.append("%(where)s")
31
- output.append(ELAPSED_TIME_FORMAT)
32
- if with_memory_usage:
33
- output.append(MEMORY_FORMAT)
34
-
35
- return "".join(output)
36
-
37
-
38
- def FormattedMessage(
14
+ def MessageWithActualExpected(
39
15
  message: str,
40
16
  /,
41
17
  *,
@@ -5,25 +5,35 @@ SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
7
  import time
8
- from datetime import datetime as dttm
8
+ from datetime import datetime as date_time_t
9
9
 
10
10
  # This module is imported early. Therefore, the current date and time should be close
11
11
  # enough to the real start time of the main script.
12
- _START_DATE_AND_TIME = dttm.now()
12
+ _START_DATE_AND_TIME = date_time_t.now()
13
13
 
14
14
 
15
15
  def TimeStamp(*, precision: str = "microseconds") -> str:
16
16
  """"""
17
- return dttm.now().isoformat(timespec=precision).replace(".", "-").replace(":", "-")
17
+ return (
18
+ date_time_t.now()
19
+ .isoformat(timespec=precision)
20
+ .replace(".", "-")
21
+ .replace(":", "-")
22
+ )
18
23
 
19
24
 
20
- def ElapsedTime() -> str:
25
+ def ElapsedTime(
26
+ *, should_return_now: bool = False
27
+ ) -> str | tuple[str, date_time_t.date]:
21
28
  """"""
22
- elapsed_seconds = (dttm.now() - _START_DATE_AND_TIME).total_seconds()
23
- output = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_seconds))
24
- while output.startswith("00") and (" " in output):
25
- output = output.split(maxsplit=1)[-1]
26
-
29
+ now = date_time_t.now()
30
+ elapsed_seconds = (now - _START_DATE_AND_TIME).total_seconds()
31
+ output = time.strftime("%H:%M:%S", time.gmtime(elapsed_seconds))
32
+ while output.startswith("00:"):
33
+ output = output.split(sep=":", maxsplit=1)[-1]
34
+
35
+ if should_return_now:
36
+ return output, now
27
37
  return output
28
38
 
29
39
 
logger_36/type/handler.py CHANGED
@@ -8,15 +8,17 @@ import dataclasses as d
8
8
  import logging as lggg
9
9
  import sys as sstm
10
10
  import typing as h
11
- from os import sep as FOLDER_SEPARATOR
12
- from pathlib import Path as path_t
13
11
 
14
- from logger_36.config.message import TIME_FORMAT, WHERE_FORMAT
12
+ from logger_36.config.message import (
13
+ LEVEL_CLOSING,
14
+ LEVEL_OPENING,
15
+ MESSAGE_MARKER,
16
+ WHERE_SEPARATOR,
17
+ )
15
18
  from logger_36.constant.error import MEMORY_MEASURE_ERROR
16
19
  from logger_36.constant.handler import HANDLER_CODES
17
20
  from logger_36.constant.message import NEXT_LINE_PROLOGUE
18
- from logger_36.constant.record import HIDE_WHERE_ATTR, SHOW_WHERE_ATTR
19
- from logger_36.task.format.message import FormattedMessage, MessageFormat
21
+ from logger_36.task.format.message import MessageWithActualExpected
20
22
  from logger_36.task.measure.chronos import TimeStamp
21
23
  from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
22
24
 
@@ -26,10 +28,9 @@ _MEMORY_MEASURE_ERROR = MEMORY_MEASURE_ERROR
26
28
  @d.dataclass(slots=True, repr=False, eq=False)
27
29
  class handler_extension_t:
28
30
  name: str | None = None
29
- show_where: bool = True
30
- show_memory_usage: bool = False
31
+ should_store_memory_usage: bool = False
31
32
  message_width: int = -1
32
- FormattedRecord: h.Callable[[lggg.LogRecord], str] = d.field(init=False)
33
+ MessageFromRecord: h.Callable[..., str] = d.field(init=False)
33
34
 
34
35
  handler: d.InitVar[lggg.Handler | None] = None
35
36
  level: d.InitVar[int] = lggg.NOTSET
@@ -43,7 +44,7 @@ class handler_extension_t:
43
44
 
44
45
  if self.name in HANDLER_CODES:
45
46
  raise ValueError(
46
- FormattedMessage(
47
+ MessageWithActualExpected(
47
48
  "Invalid handler name",
48
49
  actual=self.name,
49
50
  expected=f"a name not in {str(HANDLER_CODES)[1:-1]}",
@@ -53,8 +54,8 @@ class handler_extension_t:
53
54
  if self.name is None:
54
55
  self.name = TimeStamp()
55
56
 
56
- if self.show_memory_usage and not CanCheckMemoryUsage():
57
- self.show_memory_usage = False
57
+ if self.should_store_memory_usage and not CanCheckMemoryUsage():
58
+ self.should_store_memory_usage = False
58
59
  if _MEMORY_MEASURE_ERROR is not None:
59
60
  print(_MEMORY_MEASURE_ERROR, file=sstm.stderr)
60
61
  _MEMORY_MEASURE_ERROR = None
@@ -64,85 +65,45 @@ class handler_extension_t:
64
65
  if 0 < self.message_width < 5:
65
66
  self.message_width = 5
66
67
  if formatter is None:
67
- message_format = MessageFormat(self.show_where, self.show_memory_usage)
68
- formatter = lggg.Formatter(fmt=message_format, datefmt=TIME_FORMAT)
69
- handler.setFormatter(formatter)
70
- self.FormattedRecord = handler.formatter.format
68
+ self.MessageFromRecord = self._MessageFromRecord
69
+ else:
70
+ handler.setFormatter(formatter)
71
+ self.MessageFromRecord = handler.formatter.format
71
72
 
72
- def FormattedLines(
73
+ def _MessageFromRecord(
73
74
  self,
74
75
  record: lggg.LogRecord,
75
76
  /,
76
77
  *,
77
78
  PreProcessed: h.Callable[[str], str] | None = None,
78
- should_join_lines: bool = False,
79
- ) -> tuple[str, str | None]:
79
+ ) -> str:
80
80
  """
81
81
  See logger_36.catalog.handler.README.txt.
82
82
  """
83
- record.level_first_letter = record.levelname[0]
84
-
85
83
  message = record.msg
86
- if not isinstance(message, str):
87
- message = str(message)
88
- original_message = message
89
84
 
90
85
  if PreProcessed is not None:
91
86
  message = PreProcessed(message)
92
- if (has_newlines := ("\n" in message)) or (
93
- (self.message_width > 0) and (message.__len__() > self.message_width)
94
- ):
95
- if has_newlines:
96
- lines = message.splitlines()
97
- if self.message_width > 0:
98
- lines = _WrappedLines(lines, self.message_width)
99
- else:
100
- lines = _WrappedLines([message], self.message_width)
101
- next_lines = NEXT_LINE_PROLOGUE.join(lines[1:])
102
- next_lines = f"{NEXT_LINE_PROLOGUE}{next_lines}"
103
- message = lines[0]
87
+ if (self.message_width <= 0) or (message.__len__() <= self.message_width):
88
+ if "\n" in message:
89
+ message = NEXT_LINE_PROLOGUE.join(message.splitlines())
104
90
  else:
105
- next_lines = None
106
- if self.message_width > 0:
107
- n_missing_s = self.message_width - message.__len__()
108
- if n_missing_s > 3:
109
- message += " " + (n_missing_s - 1) * "."
110
- elif n_missing_s > 0:
111
- message += n_missing_s * " "
112
-
113
- record.msg = message
114
- if self.show_where and not hasattr(record, SHOW_WHERE_ATTR):
115
- hide_where = getattr(record, HIDE_WHERE_ATTR, False)
116
- if hide_where:
117
- record.where = ""
91
+ if "\n" in message:
92
+ lines = _WrappedLines(message.splitlines(), self.message_width)
118
93
  else:
119
- module = path_t(record.pathname)
120
- path_was_found = False
121
- for path in sstm.path:
122
- if module.is_relative_to(path):
123
- module = module.relative_to(path)
124
- path_was_found = True
125
- break
126
- if path_was_found:
127
- module = str(module.parent / module.stem)
128
- module = module.replace(FOLDER_SEPARATOR, ".")
129
- else:
130
- module = record.module
131
- record.where = WHERE_FORMAT.format(
132
- module=module, funcName=record.funcName, lineno=record.lineno
133
- )
134
- first_line = self.FormattedRecord(record).replace("\t", " ")
135
-
136
- # Revert the record message to its original value for subsequent handlers.
137
- record.msg = original_message
94
+ lines = _WrappedLines([message], self.message_width)
95
+ message = NEXT_LINE_PROLOGUE.join(lines)
138
96
 
139
- if should_join_lines:
140
- if next_lines is None:
141
- return first_line, None
142
- else:
143
- return f"{first_line}{next_lines}", None
97
+ if (where := getattr(record, "where", None)) is None:
98
+ where = ""
144
99
  else:
145
- return first_line, next_lines
100
+ where = f"{NEXT_LINE_PROLOGUE}{WHERE_SEPARATOR} {where}"
101
+
102
+ return (
103
+ f"{record.when_or_elapsed}"
104
+ f"{LEVEL_OPENING}{record.level_first_letter}{LEVEL_CLOSING} "
105
+ f"{MESSAGE_MARKER} {message}{where}"
106
+ )
146
107
 
147
108
 
148
109
  def _WrappedLines(lines: list[str], message_width: int, /) -> list[str]:
logger_36/type/issue.py CHANGED
@@ -11,7 +11,7 @@ from logger_36.config.issue import ISSUE_BASE_CONTEXT
11
11
  from logger_36.constant.generic import NOT_PASSED
12
12
  from logger_36.constant.issue import ISSUE_LEVEL_SEPARATOR
13
13
  from logger_36.constant.message import expected_op_h
14
- from logger_36.task.format.message import FormattedMessage
14
+ from logger_36.task.format.message import MessageWithActualExpected
15
15
 
16
16
  issue_t = str
17
17
 
@@ -32,7 +32,7 @@ def NewIssue(
32
32
  """"""
33
33
  if context.__len__() == 0:
34
34
  context = ISSUE_BASE_CONTEXT
35
- message = FormattedMessage(
35
+ message = MessageWithActualExpected(
36
36
  message,
37
37
  actual=actual,
38
38
  expected=expected,