From e1086e26275e93e395271d5aaa8cc51dd355e0fb Mon Sep 17 00:00:00 2001 From: DEBREUVE Eric <eric.debreuve@cnrs.fr> Date: Fri, 7 Feb 2025 11:40:34 +0100 Subject: [PATCH] slightly improved API --- package/logger_36/__init__.py | 3 +- .../logger_36/catalog/config/console_rich.py | 14 ++-- package/logger_36/catalog/handler/README.txt | 2 +- package/logger_36/catalog/handler/console.py | 14 ++-- .../logger_36/catalog/handler/console_rich.py | 14 ++-- package/logger_36/catalog/handler/file.py | 14 ++-- package/logger_36/catalog/handler/generic.py | 14 ++-- package/logger_36/catalog/logger/chronos.py | 4 +- package/logger_36/catalog/logger/gpu.py | 8 +- package/logger_36/catalog/logger/memory.py | 6 +- package/logger_36/catalog/logger/system.py | 4 +- package/logger_36/config/logger.py | 9 +-- package/logger_36/constant/logger.py | 4 +- package/logger_36/exception.py | 12 +-- package/logger_36/handler.py | 44 +++++------ package/logger_36/instance/logger.py | 2 +- package/logger_36/task/inspection.py | 6 +- package/logger_36/task/measure/chronos.py | 4 +- package/logger_36/task/storage.py | 22 +++--- package/logger_36/type/handler.py | 16 ++-- package/logger_36/type/issue.py | 4 +- package/logger_36/type/logger.py | 74 ++++++++++--------- package/logger_36/version.py | 2 +- test/main.py | 60 +++++++-------- 24 files changed, 175 insertions(+), 181 deletions(-) diff --git a/package/logger_36/__init__.py b/package/logger_36/__init__.py index d3242c6..be25c63 100644 --- a/package/logger_36/__init__.py +++ b/package/logger_36/__init__.py @@ -11,12 +11,13 @@ except ModuleNotFoundError: else: import site from pathlib import Path as path_t + paths = site.getsitepackages() + [site.getusersitepackages()] folder = path_t(__file__).parent if folder not in paths: beartype_this_package() -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L from logger_36.version import __version__ """ diff --git a/package/logger_36/catalog/config/console_rich.py b/package/logger_36/catalog/config/console_rich.py index 611b2ee..bd09679 100644 --- a/package/logger_36/catalog/config/console_rich.py +++ b/package/logger_36/catalog/config/console_rich.py @@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import logging as lggg +import logging as l from rich.color import Color as color_t from rich.style import Style as style_t @@ -16,13 +16,13 @@ WHITE_COLOR = "grey85" GRAY_COLOR = "grey58" LEVEL_COLOR: dict[int, str | style_t] = { - lggg.DEBUG: "orchid", - lggg.INFO: GRAY_COLOR, - lggg.WARNING: "yellow1", - lggg.ERROR: "dark_orange", - lggg.CRITICAL: "bright_red", + l.DEBUG: "orchid", + l.INFO: GRAY_COLOR, + l.WARNING: "yellow1", + l.ERROR: "dark_orange", + l.CRITICAL: "bright_red", } -ACTUAL_COLOR = LEVEL_COLOR[lggg.CRITICAL] +ACTUAL_COLOR = LEVEL_COLOR[l.CRITICAL] EXPECTED_COLOR = "green3" DATE_TIME_COLOR = "sky_blue3" diff --git a/package/logger_36/catalog/handler/README.txt b/package/logger_36/catalog/handler/README.txt index 40a38b7..1b54c37 100644 --- a/package/logger_36/catalog/handler/README.txt +++ b/package/logger_36/catalog/handler/README.txt @@ -1,4 +1,4 @@ ---- Note concerning: def emit(self, record: lggg.LogRecord, /) -> None: +--- Note concerning: def emit(self, record: l.LogRecord, /) -> None: The attribute "message" is not yet defined in record. It will be set by format(). Use "msg" instead. Same remark with asctime. diff --git a/package/logger_36/catalog/handler/console.py b/package/logger_36/catalog/handler/console.py index eb6a1e0..31fb26b 100644 --- a/package/logger_36/catalog/handler/console.py +++ b/package/logger_36/catalog/handler/console.py @@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg +import logging as l import textwrap as txt_ import typing as h @@ -16,15 +16,15 @@ from logger_36.type.handler import handler_extension_t @d.dataclass(slots=True, repr=False, eq=False) -class console_handler_t(lggg.Handler): +class console_handler_t(l.Handler): extension: handler_extension_t = d.field(init=False) MessageFromRecord: h.Callable[..., tuple[str, str | None]] = d.field(init=False) name: d.InitVar[str | None] = None - level: d.InitVar[int] = lggg.NOTSET + level: d.InitVar[int] = l.NOTSET should_store_memory_usage: d.InitVar[bool] = False message_width: d.InitVar[int] = -1 - formatter: d.InitVar[lggg.Formatter | None] = None + formatter: d.InitVar[l.Formatter | None] = None def __post_init__( self, @@ -32,10 +32,10 @@ class console_handler_t(lggg.Handler): level: int, should_store_memory_usage: bool, message_width: int, - formatter: lggg.Formatter | None, + formatter: l.Formatter | None, ) -> None: """""" - lggg.Handler.__init__(self) + l.Handler.__init__(self) self.extension = handler_extension_t( name=name, @@ -48,7 +48,7 @@ class console_handler_t(lggg.Handler): self.MessageFromRecord = self.extension.MessageFromRecord - def emit(self, record: lggg.LogRecord, /) -> None: + def emit(self, record: l.LogRecord, /) -> None: """""" if hasattr(record, SHOW_W_RULE_ATTR): message = RuleAsText(record.msg) diff --git a/package/logger_36/catalog/handler/console_rich.py b/package/logger_36/catalog/handler/console_rich.py index 2f9585a..3e62bca 100644 --- a/package/logger_36/catalog/handler/console_rich.py +++ b/package/logger_36/catalog/handler/console_rich.py @@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg +import logging as l import textwrap as txt_ import typing as h @@ -45,7 +45,7 @@ _EXCLUSIVE_TRACEBACK_ARGUMENTS = ( @d.dataclass(slots=True, repr=False, eq=False) -class console_rich_handler_t(lggg.Handler): +class console_rich_handler_t(l.Handler): """ alternating_lines: - Initial value: @@ -62,10 +62,10 @@ class console_rich_handler_t(lggg.Handler): background_is_light: bool = True name: d.InitVar[str | None] = None - level: d.InitVar[int] = lggg.NOTSET + level: d.InitVar[int] = l.NOTSET should_store_memory_usage: d.InitVar[bool] = False message_width: d.InitVar[int] = -1 - formatter: d.InitVar[lggg.Formatter | None] = None + formatter: d.InitVar[l.Formatter | None] = None should_install_traceback: d.InitVar[bool] = False should_record: d.InitVar[bool] = False @@ -77,13 +77,13 @@ class console_rich_handler_t(lggg.Handler): level: int, should_store_memory_usage: bool, message_width: int, - formatter: lggg.Formatter | None, + formatter: l.Formatter | None, should_install_traceback: bool, should_record: bool, rich_kwargs: dict[str, h.Any] | None, ) -> None: """""" - lggg.Handler.__init__(self) + l.Handler.__init__(self) self.extension = handler_extension_t( name=name, @@ -127,7 +127,7 @@ class console_rich_handler_t(lggg.Handler): else: self.alternating_lines = -1 - def emit(self, record: lggg.LogRecord, /) -> None: + def emit(self, record: l.LogRecord, /) -> None: """""" if hasattr(record, SHOW_W_RULE_ATTR): richer = Rule(record.msg, DATE_TIME_COLOR) diff --git a/package/logger_36/catalog/handler/file.py b/package/logger_36/catalog/handler/file.py index 4b24539..96f3a7e 100644 --- a/package/logger_36/catalog/handler/file.py +++ b/package/logger_36/catalog/handler/file.py @@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg +import logging as l import textwrap as txt_ import typing as h from pathlib import Path as path_t @@ -17,16 +17,16 @@ from logger_36.type.handler import handler_extension_t @d.dataclass(slots=True, repr=False, eq=False) -class file_handler_t(lggg.FileHandler): +class file_handler_t(l.FileHandler): extension: handler_extension_t = d.field(init=False) MessageFromRecord: h.Callable[..., tuple[str, str | None]] = d.field(init=False) name: d.InitVar[str | None] = None - level: d.InitVar[int] = lggg.NOTSET + level: d.InitVar[int] = l.NOTSET should_store_memory_usage: d.InitVar[bool] = False message_width: d.InitVar[int] = -1 - formatter: d.InitVar[lggg.Formatter | None] = None + formatter: d.InitVar[l.Formatter | None] = None path: d.InitVar[path_t | None] = None handler_args: d.InitVar[tuple[h.Any, ...] | None] = None @@ -38,13 +38,13 @@ class file_handler_t(lggg.FileHandler): level: int, should_store_memory_usage: bool, message_width: int, - formatter: lggg.Formatter | None, + formatter: l.Formatter | None, path: path_t | None, handler_args: tuple[h.Any, ...] | None, handler_kwargs: dict[str, h.Any] | None, ) -> None: """""" - lggg.FileHandler.__init__(self, path, *handler_args, **handler_kwargs) + l.FileHandler.__init__(self, path, *handler_args, **handler_kwargs) self.extension = handler_extension_t( name=name, @@ -57,7 +57,7 @@ class file_handler_t(lggg.FileHandler): self.MessageFromRecord = self.extension.MessageFromRecord - def emit(self, record: lggg.LogRecord, /) -> None: + def emit(self, record: l.LogRecord, /) -> None: """""" if hasattr(record, SHOW_W_RULE_ATTR): message = RuleAsText(record.msg) diff --git a/package/logger_36/catalog/handler/generic.py b/package/logger_36/catalog/handler/generic.py index 99fd6e3..0f743d9 100644 --- a/package/logger_36/catalog/handler/generic.py +++ b/package/logger_36/catalog/handler/generic.py @@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg +import logging as l import typing as h try: @@ -34,7 +34,7 @@ class display_rule_p(h.Protocol): @d.dataclass(slots=True, repr=False, eq=False) -class generic_handler_t(lggg.Handler): +class generic_handler_t(l.Handler): """ alternating_lines: - Initial value: @@ -66,10 +66,10 @@ class generic_handler_t(lggg.Handler): MessageFromRecord: h.Callable[..., tuple[str, str | None]] = d.field(init=False) name: d.InitVar[str | None] = None - level: d.InitVar[int] = lggg.NOTSET + level: d.InitVar[int] = l.NOTSET should_store_memory_usage: d.InitVar[bool] = False message_width: d.InitVar[int] = -1 - formatter: d.InitVar[lggg.Formatter | None] = None + formatter: d.InitVar[l.Formatter | None] = None supports_html: d.InitVar[bool] = False should_record: d.InitVar[bool] = False @@ -81,13 +81,13 @@ class generic_handler_t(lggg.Handler): level: int, should_store_memory_usage: bool, message_width: int, - formatter: lggg.Formatter | None, + formatter: l.Formatter | None, supports_html: bool, should_record: bool, rich_kwargs: dict[str, h.Any] | None, ) -> None: """""" - lggg.Handler.__init__(self) + l.Handler.__init__(self) self.extension = handler_extension_t( name=name, @@ -124,7 +124,7 @@ class generic_handler_t(lggg.Handler): else: self.alternating_lines = -1 - def emit(self, record: lggg.LogRecord, /) -> None: + def emit(self, record: l.LogRecord, /) -> None: """""" if self.console is None: if hasattr(record, SHOW_W_RULE_ATTR): diff --git a/package/logger_36/catalog/logger/chronos.py b/package/logger_36/catalog/logger/chronos.py index 03a9de1..7dfe62d 100644 --- a/package/logger_36/catalog/logger/chronos.py +++ b/package/logger_36/catalog/logger/chronos.py @@ -4,12 +4,12 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L from logger_36.task.measure.chronos import ElapsedTime from logger_36.type.logger import logger_t -def LogElapsedTime(*, logger: logger_t = LOGGER) -> None: +def LogElapsedTime(*, logger: logger_t = L) -> None: """""" logger.info(f"Elapsed Time: {ElapsedTime()}") diff --git a/package/logger_36/catalog/logger/gpu.py b/package/logger_36/catalog/logger/gpu.py index 9dd48e3..bc855ee 100644 --- a/package/logger_36/catalog/logger/gpu.py +++ b/package/logger_36/catalog/logger/gpu.py @@ -4,10 +4,10 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import sys as sstm +import sys as s from logger_36.constant.error import GPU_LOGGING_ERROR -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L from logger_36.type.logger import logger_t try: @@ -20,13 +20,13 @@ except ModuleNotFoundError: _GPU_LOGGING_ERROR = GPU_LOGGING_ERROR -def LogGPURelatedDetails(*, logger: logger_t = LOGGER) -> None: +def LogGPURelatedDetails(*, logger: logger_t = L) -> None: """""" global _GPU_LOGGING_ERROR if None in (tsfl, tsrt): if _GPU_LOGGING_ERROR is not None: - print(_GPU_LOGGING_ERROR, file=sstm.stderr) + print(_GPU_LOGGING_ERROR, file=s.stderr) _GPU_LOGGING_ERROR = None return diff --git a/package/logger_36/catalog/logger/memory.py b/package/logger_36/catalog/logger/memory.py index 2d9129c..53efe6d 100644 --- a/package/logger_36/catalog/logger/memory.py +++ b/package/logger_36/catalog/logger/memory.py @@ -6,7 +6,7 @@ SEE COPYRIGHT NOTICE BELOW from logger_36.config.memory import LENGTH_100, MAX_N_SAMPLES from logger_36.constant.memory import storage_units_h -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L from logger_36.task.format.memory import FormattedUsage, UsageBar from logger_36.task.format.message import MessageWithActualExpected from logger_36.type.logger import logger_t @@ -18,7 +18,7 @@ def LogMemoryUsages( decimals: int = None, max_n_samples: int | None = MAX_N_SAMPLES, length_100: int = LENGTH_100, - logger: logger_t = LOGGER, + logger: logger_t = L, ) -> None: """""" if not logger.any_handler_stores_memory: @@ -71,7 +71,7 @@ def LogMaximumMemoryUsage( *, unit: storage_units_h | None = "a", decimals: int | None = None, - logger: logger_t = LOGGER, + logger: logger_t = L, ) -> None: """ unit: b or None=bytes, k=kilo, m=mega, g=giga, a=auto diff --git a/package/logger_36/catalog/logger/system.py b/package/logger_36/catalog/logger/system.py index 53c99fb..e6b8c84 100644 --- a/package/logger_36/catalog/logger/system.py +++ b/package/logger_36/catalog/logger/system.py @@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW """ from logger_36.constant.system import MAX_DETAIL_NAME_LENGTH, SYSTEM_DETAILS_AS_DICT -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L from logger_36.task.inspection import Modules from logger_36.type.logger import logger_t @@ -15,7 +15,7 @@ def LogSystemDetails( modules_with_version: bool = True, modules_formatted: bool = True, should_restrict_modules_to_loaded: bool = True, - logger: logger_t = LOGGER, + logger: logger_t = L, ) -> None: """""" details = "\n".join( diff --git a/package/logger_36/config/logger.py b/package/logger_36/config/logger.py index 21b64b1..41a29ae 100644 --- a/package/logger_36/config/logger.py +++ b/package/logger_36/config/logger.py @@ -4,14 +4,14 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import logging as lggg +import logging as l from logger_36.catalog.handler.console import console_handler_t from logger_36.catalog.handler.console_rich import console_rich_handler_t from logger_36.catalog.handler.file import file_handler_t from logger_36.catalog.handler.generic import generic_handler_t from logger_36.constant.handler import HANDLER_CODES, handler_codes_h -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L from logger_36.task.format.message import MessageWithActualExpected @@ -19,15 +19,12 @@ def SetLOGLevel( level: int, /, *, - logger: lggg.Logger | None = None, + logger: l.Logger = L, which: handler_codes_h | str = "a", ) -> None: """ which: g=generic, c=console, f=file, a=all, str=name. """ - if logger is None: - logger = LOGGER - which_is_name = which not in HANDLER_CODES found = False for handler in logger.handlers: diff --git a/package/logger_36/constant/logger.py b/package/logger_36/constant/logger.py index ee7b829..53d39e7 100644 --- a/package/logger_36/constant/logger.py +++ b/package/logger_36/constant/logger.py @@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import logging as lggg +import logging as l import re as regx import typing as h @@ -17,7 +17,7 @@ WARNING_TYPE_COMPILED_PATTERN = regx.compile(WARNING_TYPE_PATTERN) # Second version: with self as first parameter. logger_handle_h = ( - h.Callable[[lggg.LogRecord], None] | h.Callable[[lggg.Logger, lggg.LogRecord], None] + h.Callable[[l.LogRecord], None] | h.Callable[[l.Logger, l.LogRecord], None] ) """ diff --git a/package/logger_36/exception.py b/package/logger_36/exception.py index 1b44dcc..2066fdc 100644 --- a/package/logger_36/exception.py +++ b/package/logger_36/exception.py @@ -4,23 +4,23 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import sys as sstm +import sys as s import tempfile as tmpf import traceback as tcbk import types as t from pathlib import Path as path_t -_ORIGINAL_EXCEPTION_HANDLER = sstm.excepthook +_ORIGINAL_EXCEPTION_HANDLER = s.excepthook def OverrideExceptionFormat() -> None: """""" - sstm.excepthook = _HandleException + s.excepthook = _HandleException def ResetExceptionFormat() -> None: """""" - sstm.excepthook = _ORIGINAL_EXCEPTION_HANDLER + s.excepthook = _ORIGINAL_EXCEPTION_HANDLER def _HandleException( @@ -36,7 +36,7 @@ def _HandleException( home = str(path_t.home()) if module.startswith(home): - module = "~" + module[home.__len__():] + module = "~" + module[home.__len__() :] message = str(exception) if message.__len__() > 0: @@ -48,7 +48,7 @@ def _HandleException( f"{stripe.__name__}\n" f" {module}.{function}@{line}\n" f"{message} Full report at: {document.name}", - file=sstm.stderr, + file=s.stderr, ) lines = tcbk.format_exception(exception) diff --git a/package/logger_36/handler.py b/package/logger_36/handler.py index b493b57..c5a6532 100644 --- a/package/logger_36/handler.py +++ b/package/logger_36/handler.py @@ -4,15 +4,14 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import logging as lggg -import sys as sstm +import logging as l +import sys as s from pathlib import Path as path_t from logger_36.catalog.handler.console import console_handler_t from logger_36.catalog.handler.file import file_handler_t from logger_36.catalog.handler.generic import generic_handler_t, show_message_p from logger_36.constant.error import MISSING_RICH_ERROR -from logger_36.instance.logger import LOGGER try: from logger_36.catalog.handler.console_rich import console_rich_handler_t @@ -27,15 +26,15 @@ except ModuleNotFoundError: def AddGenericHandler( + logger: l.Logger, ShowMessage: show_message_p, /, *, - logger: lggg.Logger | None = None, name: str | None = None, - level: int = lggg.INFO, + level: int = l.INFO, should_store_memory_usage: bool = False, message_width: int = -1, - formatter: lggg.Formatter | None = None, + formatter: l.Formatter | None = None, supports_html: bool = False, alternating_lines: int = 2, should_record: bool = False, @@ -43,9 +42,6 @@ def AddGenericHandler( **kwargs, ) -> None: """""" - if logger is None: - logger = LOGGER - handler = generic_handler_t( name=name, level=level, @@ -62,19 +58,17 @@ def AddGenericHandler( def AddConsoleHandler( + logger: l.Logger, + /, *, - logger: lggg.Logger | None = None, name: str | None = None, - level: int = lggg.INFO, + level: int = l.INFO, should_store_memory_usage: bool = False, message_width: int = -1, - formatter: lggg.Formatter | None = None, + formatter: l.Formatter | None = None, should_hold_messages: bool = False, ) -> None: """""" - if logger is None: - logger = LOGGER - handler = console_handler_t( name=name, level=level, @@ -86,13 +80,14 @@ def AddConsoleHandler( def AddRichConsoleHandler( + logger: l.Logger, + /, *, - logger: lggg.Logger | None = None, name: str | None = None, - level: int = lggg.INFO, + level: int = l.INFO, should_store_memory_usage: bool = False, message_width: int = -1, - formatter: lggg.Formatter | None = None, + formatter: l.Formatter | None = None, alternating_lines: int = 2, should_hold_messages: bool = False, should_install_traceback: bool = False, @@ -102,12 +97,9 @@ def AddRichConsoleHandler( """""" global _MISSING_RICH_ERROR if _MISSING_RICH_ERROR is not None: - print(_MISSING_RICH_ERROR, file=sstm.stderr) + print(_MISSING_RICH_ERROR, file=s.stderr) _MISSING_RICH_ERROR = None - if logger is None: - logger = LOGGER - if console_rich_handler_t is console_handler_t: additional_s = {} else: @@ -129,15 +121,15 @@ def AddRichConsoleHandler( def AddFileHandler( + logger: l.Logger, path: str | path_t, /, *args, - logger: lggg.Logger | None = None, name: str | None = None, - level: int = lggg.INFO, + level: int = l.INFO, should_store_memory_usage: bool = False, message_width: int = -1, - formatter: lggg.Formatter | None = None, + formatter: l.Formatter | None = None, should_hold_messages: bool = False, **kwargs, ) -> None: @@ -146,8 +138,6 @@ def AddFileHandler( path = path_t(path) if path.exists(): raise ValueError(f"File or folder already exists: {path}.") - if logger is None: - logger = LOGGER handler = file_handler_t( name=name, diff --git a/package/logger_36/instance/logger.py b/package/logger_36/instance/logger.py index 9fc6540..d7934e6 100644 --- a/package/logger_36/instance/logger.py +++ b/package/logger_36/instance/logger.py @@ -6,7 +6,7 @@ SEE COPYRIGHT NOTICE BELOW from logger_36.type.logger import logger_t -LOGGER = logger_t() +L = logger_t() """ COPYRIGHT NOTICE diff --git a/package/logger_36/task/inspection.py b/package/logger_36/task/inspection.py index 06d152a..80b15ba 100644 --- a/package/logger_36/task/inspection.py +++ b/package/logger_36/task/inspection.py @@ -6,7 +6,7 @@ SEE COPYRIGHT NOTICE BELOW import importlib.metadata as mprt import pkgutil as pkgs -import sys as sstm +import sys as s from types import FunctionType, MethodType @@ -17,8 +17,8 @@ def Modules( output = [] if only_loaded: - modules = sstm.modules - module_names = set(modules.keys()).difference(sstm.stdlib_module_names) + modules = s.modules + module_names = set(modules.keys()).difference(s.stdlib_module_names) module_names = sorted(module_names, key=str.lower) else: modules = None diff --git a/package/logger_36/task/measure/chronos.py b/package/logger_36/task/measure/chronos.py index dc75c94..37b57b0 100644 --- a/package/logger_36/task/measure/chronos.py +++ b/package/logger_36/task/measure/chronos.py @@ -22,9 +22,7 @@ def TimeStamp(*, precision: str = "microseconds") -> str: ) -def ElapsedTime( - *, should_return_now: bool = False -) -> str | tuple[str, date_time_t]: +def ElapsedTime(*, should_return_now: bool = False) -> str | tuple[str, date_time_t]: """""" now = date_time_t.now() elapsed_seconds = (now - _START_DATE_AND_TIME).total_seconds() diff --git a/package/logger_36/task/storage.py b/package/logger_36/task/storage.py index 8644891..cf79fe9 100644 --- a/package/logger_36/task/storage.py +++ b/package/logger_36/task/storage.py @@ -5,7 +5,7 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg +import logging as l import re as regx from html.parser import HTMLParser as html_parser_t from io import IOBase as io_base_t @@ -16,7 +16,7 @@ try: except ModuleNotFoundError: console_t = None -from logger_36.instance.logger import LOGGER +from logger_36.instance.logger import L _BODY_END_PATTERN = r"</[bB][oO][dD][yY]>(.|\n)*$" @@ -77,19 +77,19 @@ def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None: cannot_save = "Cannot save logging record as HTML" if console_t is None: - LOGGER.warning(f"{cannot_save}: The Rich console cannot be imported.") + L.warning(f"{cannot_save}: The Rich console cannot be imported.") return if path is None: - for handler in LOGGER.handlers: - if isinstance(handler, lggg.FileHandler): + for handler in L.handlers: + if isinstance(handler, l.FileHandler): path = path_t(handler.baseFilename).with_suffix(".htm") break if path is None: - LOGGER.warning(f"{cannot_save}: No file handler to build a filename from.") + L.warning(f"{cannot_save}: No file handler to build a filename from.") return if path.exists(): - LOGGER.warning( + L.warning( f'{cannot_save}: Automatically generated path "{path}" already exists.' ) return @@ -98,10 +98,10 @@ def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None: actual_file = isinstance(path, path_t) if actual_file and path.exists(): - LOGGER.warning(f'{cannot_save}: File "{path}" already exists.') + L.warning(f'{cannot_save}: File "{path}" already exists.') return - for handler in LOGGER.handlers: + for handler in L.handlers: console = getattr(handler, "console", None) if isinstance(console, console_t) and console.record: html = console.export_html() @@ -112,9 +112,7 @@ def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None: path.write(html) break else: - LOGGER.warning( - f"{cannot_save}: No handler has a RICH console with recording ON." - ) + L.warning(f"{cannot_save}: No handler has a RICH console with recording ON.") """ diff --git a/package/logger_36/type/handler.py b/package/logger_36/type/handler.py index 57bc279..88f1c0d 100644 --- a/package/logger_36/type/handler.py +++ b/package/logger_36/type/handler.py @@ -5,8 +5,8 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg -import sys as sstm +import logging as l +import sys as s import typing as h from logger_36.config.message import ( @@ -32,12 +32,12 @@ class handler_extension_t: message_width: int = -1 MessageFromRecord: h.Callable[..., str] = d.field(init=False) - handler: d.InitVar[lggg.Handler | None] = None - level: d.InitVar[int] = lggg.NOTSET - formatter: d.InitVar[lggg.Formatter | None] = None + handler: d.InitVar[l.Handler | None] = None + level: d.InitVar[int] = l.NOTSET + formatter: d.InitVar[l.Formatter | None] = None def __post_init__( - self, handler: lggg.Handler | None, level: int, formatter: lggg.Formatter | None + self, handler: l.Handler | None, level: int, formatter: l.Formatter | None ) -> None: """""" global _MEMORY_MEASURE_ERROR @@ -57,7 +57,7 @@ class handler_extension_t: if self.should_store_memory_usage and not CanCheckMemoryUsage(): self.should_store_memory_usage = False if _MEMORY_MEASURE_ERROR is not None: - print(_MEMORY_MEASURE_ERROR, file=sstm.stderr) + print(_MEMORY_MEASURE_ERROR, file=s.stderr) _MEMORY_MEASURE_ERROR = None handler.setLevel(level) @@ -72,7 +72,7 @@ class handler_extension_t: def _MessageFromRecord( self, - record: lggg.LogRecord, + record: l.LogRecord, /, *, PreProcessed: h.Callable[[str], str] | None = None, diff --git a/package/logger_36/type/issue.py b/package/logger_36/type/issue.py index e93328a..e4ced16 100644 --- a/package/logger_36/type/issue.py +++ b/package/logger_36/type/issue.py @@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -import logging as lggg +import logging as l import typing as h from logger_36.config.issue import ISSUE_BASE_CONTEXT @@ -22,7 +22,7 @@ def NewIssue( message: str, /, *, - level: int = lggg.ERROR, + level: int = l.ERROR, actual: h.Any = NOT_PASSED, expected: h.Any | None = None, expected_is_choices: bool = False, diff --git a/package/logger_36/type/logger.py b/package/logger_36/type/logger.py index 3d21e16..888d726 100644 --- a/package/logger_36/type/logger.py +++ b/package/logger_36/type/logger.py @@ -5,8 +5,8 @@ SEE COPYRIGHT NOTICE BELOW """ import dataclasses as d -import logging as lggg -import sys as sstm +import logging as l +import sys as s import traceback as tcbk import types as t import typing as h @@ -39,12 +39,14 @@ from logger_36.constant.record import ( SHOW_W_RULE_ATTR, STORE_MEMORY_ATTR, ) +from logger_36.exception import OverrideExceptionFormat +from logger_36.handler import AddRichConsoleHandler from logger_36.task.format.message import MessageWithActualExpected from logger_36.task.measure.chronos import ElapsedTime from logger_36.task.measure.memory import CurrentUsage as CurrentMemoryUsage from logger_36.type.issue import NewIssue, issue_t -logger_base_t = lggg.Logger +logger_base_t = l.Logger _DATE_TIME_ORIGIN = date_time_t.fromtimestamp(1970, None) _DATE_ORIGIN = _DATE_TIME_ORIGIN.date() @@ -56,8 +58,9 @@ class logger_t(logger_base_t): intercepted_wrn_handle: When warning interception is on, this stores the original "handle" method of the Python warning logger. """ + name_: d.InitVar[str] = LOGGER_NAME - level_: d.InitVar[int] = lggg.NOTSET + level_: d.InitVar[int] = l.NOTSET activate_wrn_interceptions: d.InitVar[bool] = True # Must not be False until at least one handler has been added. @@ -65,7 +68,7 @@ class logger_t(logger_base_t): exit_on_error: bool = False # Implies exit_on_critical. exit_on_critical: bool = False - on_hold: list[lggg.LogRecord] = d.field(init=False, default_factory=list) + on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list) events: dict[int, int] = d.field(init=False, default_factory=dict) last_message_now: date_time_t = d.field(init=False, default=_DATE_TIME_ORIGIN) last_message_date: date_t = d.field(init=False, default=_DATE_ORIGIN) @@ -86,7 +89,7 @@ class logger_t(logger_base_t): self.setLevel(level_) self.propagate = False # Part of logger_base_t. - for level in lggg.getLevelNamesMapping().values(): + for level in l.getLevelNamesMapping().values(): self.events[level] = 0 if activate_wrn_interceptions: @@ -94,6 +97,11 @@ class logger_t(logger_base_t): if self.exit_on_error: self.exit_on_critical = True + def MakeRich(self, *, alternating_lines: int = 2) -> None: + """""" + OverrideExceptionFormat() + AddRichConsoleHandler(self, alternating_lines=alternating_lines) + def ResetEventCounts(self) -> None: """""" for level in self.events: @@ -105,21 +113,21 @@ class logger_t(logger_base_t): handlers yet. """ if self.intercepted_wrn_handle is None: - logger = lggg.getLogger(WARNING_LOGGER_NAME) + logger = l.getLogger(WARNING_LOGGER_NAME) self.intercepted_wrn_handle = logger.handle logger.handle = t.MethodType(_HandleForWarnings(self), logger) - lggg.captureWarnings(True) + l.captureWarnings(True) self.info("Warning Interception: ON") def _DeactivateWarningInterceptions(self) -> None: """""" if self.intercepted_wrn_handle is not None: - logger = lggg.getLogger(WARNING_LOGGER_NAME) + logger = l.getLogger(WARNING_LOGGER_NAME) logger.handle = self.intercepted_wrn_handle self.intercepted_wrn_handle = None - lggg.captureWarnings(False) + l.captureWarnings(False) self.info("Warning Interception: OFF") def ToggleWarningInterceptions(self, state: bool, /) -> None: @@ -134,8 +142,8 @@ class logger_t(logger_base_t): if state: self.ToggleLogInterceptions(False) - all_loggers = [lggg.getLogger()] + [ - lggg.getLogger(_nme) + all_loggers = [l.getLogger()] + [ + l.getLogger(_nme) for _nme in self.manager.loggerDict if _nme not in (self.name, WARNING_LOGGER_NAME) ] @@ -151,7 +159,7 @@ class logger_t(logger_base_t): self.info(f"Now Intercepting LOGs from: {as_str}") elif self.intercepted_log_handles.__len__() > 0: for name, handle in self.intercepted_log_handles.items(): - logger = lggg.getLogger(name) + logger = l.getLogger(name) logger.handle = handle self.intercepted_log_handles.clear() self.info("Log Interception: OFF") @@ -174,7 +182,7 @@ class logger_t(logger_base_t): return "?", UNKNOWN_MEMORY_USAGE - def AddHandler(self, handler: lggg.Handler, should_hold_messages: bool, /) -> None: + def AddHandler(self, handler: l.Handler, should_hold_messages: bool, /) -> None: """""" self.should_hold_messages = should_hold_messages logger_base_t.addHandler(self, handler) @@ -195,10 +203,10 @@ class logger_t(logger_base_t): self.info( f'New handler "{name}" of type "{type(handler).__name__}" and ' - f"level {handler.level}={lggg.getLevelName(handler.level)}{path}", + f"level {handler.level}={l.getLevelName(handler.level)}{path}", ) - def handle(self, record: lggg.LogRecord, /) -> None: + def handle(self, record: l.LogRecord, /) -> None: """""" elapsed_time, now = ElapsedTime(should_return_now=True) @@ -210,10 +218,10 @@ class logger_t(logger_base_t): if (date := now.date()) != self.last_message_date: self.last_message_date = date # levelno: Added for management by logging.Logger.handle. - date_record = lggg.makeLogRecord( + date_record = l.makeLogRecord( { "name": self.name, - "levelno": lggg.INFO, + "levelno": l.INFO, "msg": f"DATE: {date.strftime(DATE_FORMAT)}", SHOW_W_RULE_ATTR: True, } @@ -235,12 +243,12 @@ class logger_t(logger_base_t): # Where. # Memory usage is also stored if there are no handlers yet, just in case. should_store_where = self.any_handler_stores_memory or not self.hasHandlers() - should_show_where = (record.levelno != lggg.INFO) and not hasattr( + should_show_where = (record.levelno != l.INFO) and not hasattr( record, HIDE_WHERE_ATTR ) if should_store_where or should_show_where: module = path_t(record.pathname) - for path in sstm.path: + for path in s.path: if module.is_relative_to(path): module = module.relative_to(path).with_suffix("") module = str(module).replace(FOLDER_SEPARATOR, ".") @@ -265,12 +273,12 @@ class logger_t(logger_base_t): else: logger_base_t.handle(self, record) - if (self.exit_on_critical and (record.levelno is lggg.CRITICAL)) or ( - self.exit_on_error and (record.levelno is lggg.ERROR) + if (self.exit_on_critical and (record.levelno is l.CRITICAL)) or ( + self.exit_on_error and (record.levelno is l.ERROR) ): - # Also works if self.exit_on_error and record.levelno is lggg.CRITICAL since + # Also works if self.exit_on_error and record.levelno is l.CRITICAL since # __post_init__ set self.exit_on_critical if self.exit_on_error. - sstm.exit(1) + s.exit(1) self.events[record.levelno] += 1 @@ -282,7 +290,7 @@ class logger_t(logger_base_t): message: str, /, *, - level: int | str = lggg.ERROR, + level: int | str = l.ERROR, actual: h.Any = NOT_PASSED, expected: h.Any | None = None, expected_is_choices: bool = False, @@ -291,7 +299,7 @@ class logger_t(logger_base_t): ) -> None: """""" if isinstance(level, str): - level = lggg.getLevelNamesMapping()[level.upper()] + level = l.getLevelNamesMapping()[level.upper()] message = MessageWithActualExpected( message, actual=actual, @@ -307,12 +315,12 @@ class logger_t(logger_base_t): exception: Exception, /, *, - level: int | str = lggg.ERROR, + level: int | str = l.ERROR, should_remove_caller: bool = False, ) -> None: """""" if isinstance(level, str): - level = lggg.getLevelNamesMapping()[level.upper()] + level = l.getLevelNamesMapping()[level.upper()] lines = tcbk.format_exception(exception) if should_remove_caller: message = "\n".join(lines[:1] + lines[2:]) @@ -359,7 +367,7 @@ class logger_t(logger_base_t): message: str, /, *, - level: int = lggg.ERROR, + level: int = l.ERROR, actual: h.Any = NOT_PASSED, expected: h.Any | None = None, expected_is_choices: bool = False, @@ -457,7 +465,7 @@ class logger_t(logger_base_t): def _HandleForWarnings(interceptor: logger_base_t, /) -> logger_handle_h: """""" - def handle_p(_: logger_base_t, record: lggg.LogRecord, /) -> None: + def handle_p(_: logger_base_t, record: l.LogRecord, /) -> None: pieces = WARNING_TYPE_COMPILED_PATTERN.match(record.msg) if pieces is None: # The warning message does not follow the default format. @@ -470,7 +478,7 @@ def _HandleForWarnings(interceptor: logger_base_t, /) -> logger_handle_h: kind = GetPiece(3) message = GetPiece(4).strip() - duplicate = lggg.makeLogRecord(record.__dict__) + duplicate = l.makeLogRecord(record.__dict__) duplicate.msg = f"{kind}: {message}" duplicate.pathname = path duplicate.module = path_t(path).stem @@ -487,8 +495,8 @@ def _HandleForInterceptions( ) -> logger_handle_h: """""" - def handle_p(_: logger_base_t, record: lggg.LogRecord, /) -> None: - duplicate = lggg.makeLogRecord(record.__dict__) + def handle_p(_: logger_base_t, record: l.LogRecord, /) -> None: + duplicate = l.makeLogRecord(record.__dict__) duplicate.msg = f"{record.msg} :{intercepted.name}:" interceptor.handle(duplicate) diff --git a/package/logger_36/version.py b/package/logger_36/version.py index 2993d2b..c4211f1 100644 --- a/package/logger_36/version.py +++ b/package/logger_36/version.py @@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023 SEE COPYRIGHT NOTICE BELOW """ -__version__ = "2025.4" +__version__ = "2025.5" """ COPYRIGHT NOTICE diff --git a/test/main.py b/test/main.py index 9650bf4..5e5101c 100644 --- a/test/main.py +++ b/test/main.py @@ -5,15 +5,15 @@ SEE COPYRIGHT NOTICE BELOW """ import difflib as diff -import logging as lggg -import sys as sstm +import logging as l +import sys as s import uuid import warnings as wrng from io import StringIO as fake_file_t from pathlib import Path as path_t from tempfile import TemporaryDirectory -from logger_36 import LOGGER +from logger_36 import L from logger_36.api.storage import html_reader_t from logger_36.handler import AddFileHandler, AddGenericHandler, AddRichConsoleHandler from logger_36.memory import LogMaximumMemoryUsage, LogMemoryUsages @@ -37,12 +37,12 @@ def HighlightedHTML(html: str, /) -> str: return pgmt.highlight(html, html_lexer_t(), terminal_formatter_t()) -other_logger = lggg.getLogger(str(uuid.uuid1())) -handler = lggg.StreamHandler() -formatter = lggg.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +other_logger = l.getLogger(str(uuid.uuid1())) +handler = l.StreamHandler() +formatter = l.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") # handler.setFormatter(formatter) -other_logger.setLevel(lggg.DEBUG) +other_logger.setLevel(l.DEBUG) other_logger.propagate = False other_logger.addHandler(handler) @@ -51,64 +51,66 @@ with TemporaryDirectory() as tmp_folder: tmp_file = tmp_folder / "log.txt" AddRichConsoleHandler( - level=lggg.DEBUG, + L, + level=l.DEBUG, should_store_memory_usage=True, should_hold_messages=True, should_record=True, alternating_lines=1, ) AddGenericHandler( + L, lambda _msg, indented=False: print(_msg), message_width=80, should_hold_messages=True, ) - AddFileHandler(tmp_file, should_store_memory_usage=True) # Level=lggg.INFO. - LOGGER.ToggleLogInterceptions(True) + AddFileHandler(L, tmp_file, should_store_memory_usage=True) # Level=l.INFO. + L.ToggleLogInterceptions(True) LogSystemDetails() - LOGGER.DisplayRule() + L.DisplayRule() for level in ("debug", "info", "warning", "error", "critical"): - LogMessage = getattr(LOGGER, level) + LogMessage = getattr(L, level) LogMessage(f"{level.capitalize()} message") LogMessage(f"Multi-line\n{level.capitalize()}\nmessage") - LOGGER.info(VERY_LONG_LINE) - LOGGER.info(f"{VERY_LONG_LINE}...\n...with a newline") + L.info(VERY_LONG_LINE) + L.info(f"{VERY_LONG_LINE}...\n...with a newline") - LOGGER.ShowMessage("RAW MESSAGE") + L.ShowMessage("RAW MESSAGE") - LOGGER.StageIssue( + L.StageIssue( "INITIAL Issue Dictionary", actual={}, expected="non-empty dictionary", expected_op=":", ) - with LOGGER.AddedContextLevel("Level one"): - LOGGER.StageIssue("Issue Int/Tuple", actual=0, expected=(1, 2)) - LOGGER.StageIssue( + with L.AddedContextLevel("Level one"): + L.StageIssue("Issue Int/Tuple", actual=0, expected=(1, 2)) + L.StageIssue( "Issue Str/Dict", actual="", expected="a dictionary", expected_op=":" ) - LOGGER.StageIssue( + L.StageIssue( "Issue None/Int", actual=None, expected="an integer", expected_op=":" ) - with LOGGER.AddedContextLevel("Level two"): - LOGGER.StageIssue("Issue List/Tuple", actual=[1, 2, 3], expected=(1, 2, 3)) - LOGGER.StageIssue( + with L.AddedContextLevel("Level two"): + L.StageIssue("Issue List/Tuple", actual=[1, 2, 3], expected=(1, 2, 3)) + L.StageIssue( "Issue Set", actual=set(), expected="non-empty set", expected_op=":" ) - LOGGER.StageIssue("FINAL Issue") - LOGGER.CommitIssues(unified=True) - # Alternatively, raise an exception with, e.g.: LOGGER.CommitIssues(ValueError) + L.StageIssue("FINAL Issue") + L.CommitIssues(unified=True) + # Alternatively, raise an exception with, e.g.: L.CommitIssues(ValueError) wrng.warn("Warning capture test") - LOGGER.ToggleWarningInterceptions(False) + L.ToggleWarningInterceptions(False) wrng.warn("Warning capture test: THIS SHOULD NOT BE INTERCEPTED") other_logger.info("Log capture test") - LOGGER.ToggleLogInterceptions(False) + L.ToggleLogInterceptions(False) other_logger.info("Log capture test: THIS SHOULD NOT BE INTERCEPTED") LogMaximumMemoryUsage() @@ -133,7 +135,7 @@ html_body_as_text = html_reader.body_as_text print(f"\n--- De HTMLed (from console; level=DEBUG)\n{html_body_as_text}") print("\n--- Comparison LOG File (level=INFO) / De HTMLed (level=DEBUG)") -sstm.stdout.writelines( +s.stdout.writelines( diff.context_diff( content.splitlines(keepends=True), html_body_as_text.splitlines(keepends=True), -- GitLab