From 981c4ed1ec4bf8fd3ec97f343edca6291fdb571a Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 20:28:46 -0400 Subject: [PATCH 01/26] Make `level_for()` private --- adafruit_logging/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index f5bcdf4..a9be055 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -63,7 +63,7 @@ "WARNING", "ERROR", "CRITICAL", - "level_for", + "_level_for", "LoggingHandler", "PrintHandler", "logger_cache", @@ -87,7 +87,7 @@ globals()[__name] = __value -def level_for(value: int) -> str: +def _level_for(value: int) -> str: """Convert a numeric level to the most appropriate name. :param int value: a numeric level @@ -112,7 +112,7 @@ def format(self, log_level: int, message: str) -> str: """ return "{0:<0.3f}: {1} - {2}".format( - time.monotonic(), level_for(log_level), message + time.monotonic(), _level_for(log_level), message ) def emit(self, log_level: int, message: str): From 1de0e3ea2be0ea744054d2e5b536e1f0711ad385 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 20:35:14 -0400 Subject: [PATCH 02/26] Make `format` private to not confict with CPython --- adafruit_logging/__init__.py | 4 ++-- adafruit_logging/extensions.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index a9be055..9a4342c 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -104,7 +104,7 @@ def _level_for(value: int) -> str: class LoggingHandler: """Abstract logging message handler.""" - def format(self, log_level: int, message: str) -> str: + def _format(self, log_level: int, message: str) -> str: """Generate a timestamped message. :param int log_level: the logging level @@ -132,7 +132,7 @@ def emit(self, log_level: int, message: str): :param str message: the message to log """ - print(self.format(log_level, message)) + print(self._format(log_level, message)) # The level module-global variables get created when loaded diff --git a/adafruit_logging/extensions.py b/adafruit_logging/extensions.py index 0ea110a..3843220 100644 --- a/adafruit_logging/extensions.py +++ b/adafruit_logging/extensions.py @@ -34,13 +34,13 @@ def close(self): """Closes the file""" self.logfile.close() - def format(self, log_level: int, message: str): + def _format(self, log_level: int, message: str): """Generate a string to log :param level: The level of the message :param msg: The message to format """ - return super().format(log_level, message) + "\r\n" + return super()._format(log_level, message) + "\r\n" def emit(self, log_level: int, message: str): """Generate the message and write it to the UART. @@ -48,4 +48,4 @@ def emit(self, log_level: int, message: str): :param level: The level of the message :param msg: The message to log """ - self.logfile.write(self.format(log_level, message)) + self.logfile.write(self._format(log_level, message)) From 9e11346c23051064f6bfce7a32a222373aef6960 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:27:09 -0400 Subject: [PATCH 03/26] Transform LoggingHandler to Handler --- adafruit_logging/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index 9a4342c..d7f85ef 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -101,9 +101,14 @@ def _level_for(value: int) -> str: return LEVELS[0][1] -class LoggingHandler: +class Handler: """Abstract logging message handler.""" + def __init__(self, level=NOTSET): + self.level = level + """Level of the handler; this is currently unused, and + only the level of the logger is used""" + def _format(self, log_level: int, message: str) -> str: """Generate a timestamped message. @@ -115,7 +120,7 @@ def _format(self, log_level: int, message: str) -> str: time.monotonic(), _level_for(log_level), message ) - def emit(self, log_level: int, message: str): + def _emit(self, log_level: int, message: str): """Send a message where it should go. Placeholder for subclass implementations. """ From 06ee36690e88ddf14bace2633aaee8c1abf702df Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:27:53 -0400 Subject: [PATCH 04/26] Convert PrintHandler to StreamHandler with default --- adafruit_logging/__init__.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index d7f85ef..646e245 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -127,10 +127,21 @@ def _emit(self, log_level: int, message: str): raise NotImplementedError() -class PrintHandler(LoggingHandler): - """Send logging messages to the console by using print.""" +class StreamHandler(Handler): + """Send logging messages to a stream, `sys.stderr` (typically + the serial console) by default. + + :param stream: The stream to log to, default is `sys.stderr` + """ - def emit(self, log_level: int, message: str): + def __init__(self, stream=None): + super.__init__(self) + if stream is None: + stream = sys.stderr + self.stream = stream + """The stream to log to""" + + def _emit(self, log_level: int, message: str): """Send a message to the console. :param int log_level: the logging level From 6d5609cddfbb3c1df1bfbddc012b33f7bedab38b Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:28:50 -0400 Subject: [PATCH 05/26] getLogger() default return is None, remove `null_logger` --- adafruit_logging/__init__.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index 646e245..cd6f909 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -155,25 +155,19 @@ def _emit(self, log_level: int, message: str): # pylint:disable=undefined-variable logger_cache = {} -null_logger = None # pylint:disable=global-statement def getLogger(logger_name: str) -> "Logger": - """Create or retrieve a logger by name. + """Create or retrieve a logger by name. Only caches loggers + made using this function, and does not cache any made directly. :param str logger_name: The name of the `Logger` to create/retrieve. `None` will cause the `NullLogger` instance to be returned. """ - global null_logger - if not logger_name or logger_name == "": - if not null_logger: - null_logger = NullLogger() - return null_logger - if logger_name not in logger_cache: - logger_cache[logger_name] = Logger() - return logger_cache[logger_name] + logger_cache[logger_name] = Logger(logger_name) + return logger_cache.get(logger_name, None) # pylint:enable=global-statement From 5206a8d7e42155bab65c269b1967bfa56d58a4f9 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:33:11 -0400 Subject: [PATCH 06/26] Add function for adding logger to global dict --- adafruit_logging/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index cd6f909..6e3d8e8 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -156,6 +156,11 @@ def _emit(self, log_level: int, message: str): logger_cache = {} +def _addLogger(logger_name: str): + """Adds the logger if it doesn't already exist""" + if logger_name not in logger_cache: + logger_cache[logger_name] = Logger(logger_name) + # pylint:disable=global-statement def getLogger(logger_name: str) -> "Logger": """Create or retrieve a logger by name. Only caches loggers From 0c8c08e569a68d3501be595678ceb8f6f21effc0 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:33:55 -0400 Subject: [PATCH 07/26] getLogger() uses _addLogger(), default return is None --- adafruit_logging/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index 6e3d8e8..b13dcc4 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -163,15 +163,13 @@ def _addLogger(logger_name: str): # pylint:disable=global-statement def getLogger(logger_name: str) -> "Logger": - """Create or retrieve a logger by name. Only caches loggers - made using this function, and does not cache any made directly. + """Create or retrieve a logger by name :param str logger_name: The name of the `Logger` to create/retrieve. `None` will cause the `NullLogger` instance to be returned. """ - if logger_name not in logger_cache: - logger_cache[logger_name] = Logger(logger_name) + _addLogger(logger_name) return logger_cache.get(logger_name, None) From b925c035ffa93a8a1ad4128f733220bb8a10215b Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:34:26 -0400 Subject: [PATCH 08/26] Logger() takes name and level args --- adafruit_logging/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index b13dcc4..ff7bb63 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -179,10 +179,14 @@ def getLogger(logger_name: str) -> "Logger": class Logger: """Provide a logging api.""" - def __init__(self): + def __init__(self, name: str, level=NOTSET): """Create an instance.""" - self._level = NOTSET - self._handler = PrintHandler() + self._level = level + self.name = name + """The name of the logger, this should be unique for proper + functionality of `getLogger()`""" + self._handler = None + _addLogger(name) def setLevel(self, log_level: int): """Set the logging cutoff level. From ef98f1b05d6fc0719c4a70abf80d808061662686 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:34:48 -0400 Subject: [PATCH 09/26] Fix typeannotation of addHandler() --- adafruit_logging/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index ff7bb63..6668cb1 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -204,8 +204,9 @@ def getEffectiveLevel(self) -> int: """ return self._level - def addHandler(self, handler: LoggingHandler): + def addHandler(self, handler: Handler): """Sets the handler of this logger to the specified handler. + *NOTE* this is slightly different from the CPython equivalent which adds the handler rather than replacing it. From d7217524028ee24090e04584aca2462bc069d698 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:35:39 -0400 Subject: [PATCH 10/26] Add hasHandlers() to compensate for changes to functionality --- adafruit_logging/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index 6668cb1..1d63c92 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -215,7 +215,11 @@ def addHandler(self, handler: Handler): """ self._handler = handler - def log(self, log_level: int, format_string: str, *args): + def hasHandlers(self) -> bool: + """Whether any handlers have been set for this logger""" + return self._handler is not None + + def log(self, level: int, msg: str, *args): """Log a message. :param int log_level: the priority level at which to log From 800c3776b5da5b46a44af2b2c236733fe221bc2b Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:36:36 -0400 Subject: [PATCH 11/26] Logging methods now account for changes, arg name changes --- adafruit_logging/__init__.py | 39 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index 1d63c92..929be0d 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -222,64 +222,65 @@ def hasHandlers(self) -> bool: def log(self, level: int, msg: str, *args): """Log a message. - :param int log_level: the priority level at which to log - :param str format_string: the core message string with embedded + :param int level: the priority level at which to log + :param str msg: the core message string with embedded formatting directives :param args: arguments to ``format_string.format()``; can be empty """ - if log_level >= self._level: - self._handler.emit(log_level, format_string % args) + if level >= self._level: + self._handler._emit(level, msg % args) - def debug(self, format_string: str, *args): + def debug(self, msg: str, *args): """Log a debug message. - :param str format_string: the core message string with embedded + :param str fmsg: the core message string with embedded formatting directives :param args: arguments to ``format_string.format()``; can be empty """ - self.log(DEBUG, format_string, *args) + self.log(DEBUG, msg, *args) - def info(self, format_string: str, *args): + def info(self, msg: str, *args): """Log a info message. - :param str format_string: the core message string with embedded + :param str msg: the core message string with embedded formatting directives :param args: arguments to ``format_string.format()``; can be empty """ - self.log(INFO, format_string, *args) + self.log(INFO, msg, *args) - def warning(self, format_string: str, *args): + def warning(self, msg: str, *args): """Log a warning message. - :param str format_string: the core message string with embedded + :param str msg: the core message string with embedded formatting directives :param args: arguments to ``format_string.format()``; can be empty """ - self.log(WARNING, format_string, *args) + self.log(WARNING, msg, *args) - def error(self, format_string: str, *args): + def error(self, msg: str, *args): """Log a error message. - :param str format_string: the core message string with embedded + :param str msg: the core message string with embedded formatting directives :param args: arguments to ``format_string.format()``; can be empty """ - self.log(ERROR, format_string, *args) + self.log(ERROR, msg, *args) - def critical(self, format_string: str, *args): + def critical(self, msg: str, *args): """Log a critical message. - :param str format_string: the core message string with embedded + :param str msg: the core message string with embedded formatting directives :param args: arguments to ``format_string.format()``; can be empty """ - self.log(CRITICAL, format_string, *args) + self.log(CRITICAL, msg, *args) + class NullLogger: From 393d878c168a1f206eddf6b8b788960e641b1f61 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:37:10 -0400 Subject: [PATCH 12/26] NullLogger is now NullHandler --- adafruit_logging/__init__.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index 929be0d..a4a668b 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -282,15 +282,12 @@ def critical(self, msg: str, *args): self.log(CRITICAL, msg, *args) +class NullHandler(Handler): + """Provide an empty log handler. -class NullLogger: - """Provide an empty logger. - This can be used in place of a real logger to more efficiently disable + This can be used in place of a real log handler to more efficiently disable logging.""" - def __init__(self): - """Dummy implementation.""" - def setLevel(self, log_level: int): """Dummy implementation.""" From 69821d2387b44bf21c21d49756939c8a677de4b8 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:37:46 -0400 Subject: [PATCH 13/26] addHandler() type annotation updated --- adafruit_logging/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index a4a668b..b25973f 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -295,7 +295,7 @@ def getEffectiveLevel(self) -> int: """Dummy implementation.""" return NOTSET - def addHandler(self, handler: LoggingHandler): + def addHandler(self, handler: Handler): """Dummy implementation.""" def log(self, log_level: int, format_string: str, *args): From e53bcf22d3f7d46e2d5835b4eb3d88003e8215b0 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:38:03 -0400 Subject: [PATCH 14/26] FileHandler moved to __init__,py --- adafruit_logging/__init__.py | 44 ++++++++++++++++++++++++++--- adafruit_logging/extensions.py | 51 ---------------------------------- 2 files changed, 40 insertions(+), 55 deletions(-) delete mode 100644 adafruit_logging/extensions.py diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index b25973f..6db5298 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -51,6 +51,7 @@ # pylint:disable=invalid-name import time +import sys __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Logger.git" @@ -64,13 +65,13 @@ "ERROR", "CRITICAL", "_level_for", - "LoggingHandler", - "PrintHandler", + "Handler", + "StreamHandler", "logger_cache", - "null_logger", "getLogger", "Logger", - "NullLogger", + "NullHandler", + "FileHandler", ] @@ -315,3 +316,38 @@ def error(self, format_string: str, *args): def critical(self, format_string: str, *args): """Dummy implementation.""" + + +class FileHandler(StreamHandler): + """File handler for working with log files off of the microcontroller (like + an SD card) + + :param str filename: The filename of the log file + :param str mode: Whether to write ('w') or append ('a'); default is to append + """ + + def __init__(self, filename: str, mode: str = "a") -> None: + self.logfile = open( # pylint: disable=consider-using-with + filename, mode, encoding="utf-8" + ) + + def close(self): + """Closes the file""" + self.logfile.close() + + def _format(self, log_level: int, message: str): + """Generate a string to log + + :param level: The level of the message + :param msg: The message to format + """ + return super()._format(log_level, message) + "\r\n" + + def _emit(self, log_level: int, message: str): + """Generate the message and write it to the UART. + + :param level: The level of the message + :param msg: The message to log + """ + self.logfile.write(self._format(log_level, message)) + diff --git a/adafruit_logging/extensions.py b/adafruit_logging/extensions.py deleted file mode 100644 index 3843220..0000000 --- a/adafruit_logging/extensions.py +++ /dev/null @@ -1,51 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Alec Delaney for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -""" -`extensions` -==================================================== - -CircuitPython logging extension for logging to files - -* Author(s): Alec Delaney -""" - -from . import LoggingHandler - -__version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Logging.git" - - -class FileHandler(LoggingHandler): - """File handler for working with log files off of the microcontroller (like - an SD card) - - :param filepath: The filepath to the log file - :param mode: Whether to write ('w') or append ('a'); default is to append - """ - - def __init__(self, filepath: str, mode: str = "a"): - self.logfile = open( # pylint: disable=consider-using-with - filepath, mode, encoding="utf-8" - ) - - def close(self): - """Closes the file""" - self.logfile.close() - - def _format(self, log_level: int, message: str): - """Generate a string to log - - :param level: The level of the message - :param msg: The message to format - """ - return super()._format(log_level, message) + "\r\n" - - def emit(self, log_level: int, message: str): - """Generate the message and write it to the UART. - - :param level: The level of the message - :param msg: The message to log - """ - self.logfile.write(self._format(log_level, message)) From 1eae0186b4abf44239804053ced6b0536fee8c08 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:39:59 -0400 Subject: [PATCH 15/26] adafruit_logging changed to file py_module --- adafruit_logging/__init__.py => adafruit_logging.py | 0 setup.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename adafruit_logging/__init__.py => adafruit_logging.py (100%) diff --git a/adafruit_logging/__init__.py b/adafruit_logging.py similarity index 100% rename from adafruit_logging/__init__.py rename to adafruit_logging.py diff --git a/setup.py b/setup.py index 60ade1a..428e4c2 100644 --- a/setup.py +++ b/setup.py @@ -50,5 +50,5 @@ keywords="adafruit blinka circuitpython micropython logging logger", # You can just specify the packages manually here if your project is # simple. Or you can use find_packages(). - packages=["adafruit_logging"], + py_modules=["adafruit_logging"], ) From 880b850eca8043af17124764f9ec315d1bf3cbf6 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:40:18 -0400 Subject: [PATCH 16/26] Reformatted per pre-commit --- adafruit_logging.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 6db5298..1742d91 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -131,7 +131,7 @@ def _emit(self, log_level: int, message: str): class StreamHandler(Handler): """Send logging messages to a stream, `sys.stderr` (typically the serial console) by default. - + :param stream: The stream to log to, default is `sys.stderr` """ @@ -141,7 +141,7 @@ def __init__(self, stream=None): stream = sys.stderr self.stream = stream """The stream to log to""" - + def _emit(self, log_level: int, message: str): """Send a message to the console. @@ -157,11 +157,13 @@ def _emit(self, log_level: int, message: str): logger_cache = {} + def _addLogger(logger_name: str): """Adds the logger if it doesn't already exist""" if logger_name not in logger_cache: logger_cache[logger_name] = Logger(logger_name) + # pylint:disable=global-statement def getLogger(logger_name: str) -> "Logger": """Create or retrieve a logger by name @@ -350,4 +352,3 @@ def _emit(self, log_level: int, message: str): :param msg: The message to log """ self.logfile.write(self._format(log_level, message)) - From 7a796da214f97a03cc22f4f71c51f65867f77327 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 21:49:44 -0400 Subject: [PATCH 17/26] Linted, reformatted per pre-commit --- adafruit_logging.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 1742d91..fca9ece 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -102,10 +102,11 @@ def _level_for(value: int) -> str: return LEVELS[0][1] +# pylint: disable=too-few-public-methods class Handler: """Abstract logging message handler.""" - def __init__(self, level=NOTSET): + def __init__(self, level=NOTSET): # pylint: disable=undefined-variable self.level = level """Level of the handler; this is currently unused, and only the level of the logger is used""" @@ -128,6 +129,7 @@ def _emit(self, log_level: int, message: str): raise NotImplementedError() +# pylint: disable=too-few-public-methods class StreamHandler(Handler): """Send logging messages to a stream, `sys.stderr` (typically the serial console) by default. @@ -136,7 +138,7 @@ class StreamHandler(Handler): """ def __init__(self, stream=None): - super.__init__(self) + super().__init__() if stream is None: stream = sys.stderr self.stream = stream @@ -232,7 +234,7 @@ def log(self, level: int, msg: str, *args): """ if level >= self._level: - self._handler._emit(level, msg % args) + self._handler._emit(level, msg % args) # pylint: disable=protected-access def debug(self, msg: str, *args): """Log a debug message. @@ -319,6 +321,9 @@ def error(self, format_string: str, *args): def critical(self, format_string: str, *args): """Dummy implementation.""" + def _emit(self, log_level: int, message: str): + """Dummy implementation""" + class FileHandler(StreamHandler): """File handler for working with log files off of the microcontroller (like @@ -329,13 +334,12 @@ class FileHandler(StreamHandler): """ def __init__(self, filename: str, mode: str = "a") -> None: - self.logfile = open( # pylint: disable=consider-using-with - filename, mode, encoding="utf-8" - ) + # pylint: disable=consider-using-with + super().__init__(open(filename, mode=mode)) def close(self): """Closes the file""" - self.logfile.close() + self.stream.close() def _format(self, log_level: int, message: str): """Generate a string to log @@ -351,4 +355,4 @@ def _emit(self, log_level: int, message: str): :param level: The level of the message :param msg: The message to log """ - self.logfile.write(self._format(log_level, message)) + self.stream.write(self._format(log_level, message)) From 30ceea1c0b6186b50739588601ea47f9115c7b23 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 22:01:43 -0400 Subject: [PATCH 18/26] Update examples --- examples/logging_filehandler.py | 2 +- examples/logging_simpletest.py | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index 37e5de6..e96015f 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -7,7 +7,7 @@ import storage import adafruit_sdcard import adafruit_logging as logging -from adafruit_logging.extensions import FileHandler +from adafruit_logging import FileHandler # Get chip select pin depending on the board, this one is for the Feather M4 Express sd_cs = board.D10 diff --git a/examples/logging_simpletest.py b/examples/logging_simpletest.py index 3286bce..c6c7d4a 100644 --- a/examples/logging_simpletest.py +++ b/examples/logging_simpletest.py @@ -19,14 +19,7 @@ # This should produce no output null_logger = logging.getLogger(None) - -null_logger.setLevel(logging.ERROR) -null_logger.info("Info message") -null_logger.error("Error message") - -# This should produce no output - -null_logger = logging.getLogger("") +null_logger.addHandler(logging.NullHandler) null_logger.setLevel(logging.ERROR) null_logger.info("Info message") From a8d103724a4d33097eef5bd4cd9cc4f2f36fe9d0 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 22:03:18 -0400 Subject: [PATCH 19/26] Fixed getLogger() docstring --- adafruit_logging.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index fca9ece..c4b75bf 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -170,8 +170,7 @@ def _addLogger(logger_name: str): def getLogger(logger_name: str) -> "Logger": """Create or retrieve a logger by name - :param str logger_name: The name of the `Logger` to create/retrieve. `None` - will cause the `NullLogger` instance to be returned. + :param str logger_name: The name of the `Logger` to create/retrieve. """ _addLogger(logger_name) From 61fd3cf0233adb822089807a57e6d9d64f003d7a Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 22:13:41 -0400 Subject: [PATCH 20/26] Prevent recursive _addLogger() and __init__() --- adafruit_logging.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index c4b75bf..387f44e 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -168,7 +168,8 @@ def _addLogger(logger_name: str): # pylint:disable=global-statement def getLogger(logger_name: str) -> "Logger": - """Create or retrieve a logger by name + """Create or retrieve a logger by name; only retrieves loggers + made using this function :param str logger_name: The name of the `Logger` to create/retrieve. @@ -190,7 +191,6 @@ def __init__(self, name: str, level=NOTSET): """The name of the logger, this should be unique for proper functionality of `getLogger()`""" self._handler = None - _addLogger(name) def setLevel(self, log_level: int): """Set the logging cutoff level. From 969f3b0c3c8f5c7de758d1479fce9ac162a3df5e Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 22:21:51 -0400 Subject: [PATCH 21/26] Change arg names --- adafruit_logging.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 387f44e..07f2005 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -305,19 +305,19 @@ def addHandler(self, handler: Handler): def log(self, log_level: int, format_string: str, *args): """Dummy implementation.""" - def debug(self, format_string: str, *args): + def debug(self, msg: str, *args): """Dummy implementation.""" - def info(self, format_string: str, *args): + def info(self, msg: str, *args): """Dummy implementation.""" - def warning(self, format_string: str, *args): + def warning(self, msg: str, *args): """Dummy implementation.""" - def error(self, format_string: str, *args): + def error(self, msg: str, *args): """Dummy implementation.""" - def critical(self, format_string: str, *args): + def critical(self, msg: str, *args): """Dummy implementation.""" def _emit(self, log_level: int, message: str): From 15fc22f8970ea6f66082ce58bf8db8588380e9f1 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 22:22:10 -0400 Subject: [PATCH 22/26] Fix simple test example --- examples/logging_simpletest.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/logging_simpletest.py b/examples/logging_simpletest.py index c6c7d4a..425565c 100644 --- a/examples/logging_simpletest.py +++ b/examples/logging_simpletest.py @@ -11,6 +11,8 @@ # This should produce an error output logger = logging.getLogger("test") +print_logger = logging.StreamHandler() +logger.addHandler(print_logger) logger.setLevel(logging.ERROR) logger.info("Info message") @@ -19,7 +21,8 @@ # This should produce no output null_logger = logging.getLogger(None) -null_logger.addHandler(logging.NullHandler) +null_handler = logging.NullHandler() +null_logger.addHandler(null_handler) null_logger.setLevel(logging.ERROR) null_logger.info("Info message") From 75cf4c9d4e9a0b8ea10ac7fb2ab82ccf09a96178 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 22:54:14 -0400 Subject: [PATCH 23/26] Update file logging example --- examples/logging_filehandler.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index e96015f..92f9d0d 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -28,3 +28,6 @@ logger.info("Logger initialized!") logger.debug("You can even add debug statements to the log!") + +# If you're done with the FileHandler, close it +file_handler.close() From 335af26db04d56ca28d28a12f1f86f3683298998 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 21 May 2022 23:03:35 -0400 Subject: [PATCH 24/26] Logger names should be strings --- examples/logging_simpletest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/logging_simpletest.py b/examples/logging_simpletest.py index 425565c..3eb258b 100644 --- a/examples/logging_simpletest.py +++ b/examples/logging_simpletest.py @@ -20,7 +20,7 @@ # This should produce no output -null_logger = logging.getLogger(None) +null_logger = logging.getLogger("null") null_handler = logging.NullHandler() null_logger.addHandler(null_handler) From 6faddada2a07bf825152ca054c1f338682a47141 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 28 May 2022 12:58:47 -0400 Subject: [PATCH 25/26] Change arg name for addHandler() --- adafruit_logging.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 07f2005..33f6c4c 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -208,7 +208,7 @@ def getEffectiveLevel(self) -> int: """ return self._level - def addHandler(self, handler: Handler): + def addHandler(self, hdlr: Handler): """Sets the handler of this logger to the specified handler. *NOTE* this is slightly different from the CPython equivalent which adds @@ -217,7 +217,7 @@ def addHandler(self, handler: Handler): :param LoggingHandler handler: the handler """ - self._handler = handler + self._handler = hdlr def hasHandlers(self) -> bool: """Whether any handlers have been set for this logger""" From 85ad94cd12249bcd1ea44fa1deb582975d577f59 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sat, 28 May 2022 13:01:20 -0400 Subject: [PATCH 26/26] Use brackets to get logger in getLogger() --- adafruit_logging.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 33f6c4c..0217e8b 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -169,13 +169,14 @@ def _addLogger(logger_name: str): # pylint:disable=global-statement def getLogger(logger_name: str) -> "Logger": """Create or retrieve a logger by name; only retrieves loggers - made using this function + made using this function; if a Logger with this name does not + exist it is created :param str logger_name: The name of the `Logger` to create/retrieve. """ _addLogger(logger_name) - return logger_cache.get(logger_name, None) + return logger_cache[logger_name] # pylint:enable=global-statement