From e875b653213e85562a50582f199de28b8260a7fe Mon Sep 17 00:00:00 2001 From: Scott Wallace Date: Sat, 11 Dec 2021 17:10:44 +0000 Subject: [PATCH] Strict typing --- common_logger.py | 71 +++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/common_logger.py b/common_logger.py index 98910e3..4c60086 100644 --- a/common_logger.py +++ b/common_logger.py @@ -12,9 +12,10 @@ import logging.handlers import os.path import socket import sys +from typing import Any, Optional import dateutil.tz -import psutil +import psutil # type: ignore[import] import pytz DEBUG = logging.DEBUG @@ -31,12 +32,6 @@ PLATFORM_DEFS = { 'socket': '/var/run/syslog', 'logdir': os.path.expanduser('~/Library/Logs'), }, - # Python2 - 'linux2': { - 'socket': '/dev/log', - 'logdir': '/srv/log', - }, - # Python3 'linux': { 'socket': '/dev/log', 'logdir': '/srv/log', @@ -50,27 +45,30 @@ class UcFormatter(logging.Formatter): """ @staticmethod - def _get_local_tz_str(): + def _get_local_tz_str() -> str: """ Method to fetch the correct location-string for the local timezone e.g. returns "Europe/London" """ - # pylint: disable=protected-access return '/'.join( - os.path.realpath(dateutil.tz.gettz()._filename).split('/')[-2:] - ) # pyright: reportGeneralTypeIssues=false + os.path.realpath( + dateutil.tz.gettz()._filename # type: ignore[union-attr] # pylint: disable=protected-access + ).split('/')[-2:] + ) - def converter(self, timestamp): + def converter(self, timestamp: Optional[float]) -> datetime.datetime: # type: ignore[override] """ Method to add the local timezone to the the provided timestamp """ - tsdt = datetime.datetime.fromtimestamp(timestamp) + tsdt = datetime.datetime.fromtimestamp(timestamp or 0.0) tzinfo = pytz.timezone(self._get_local_tz_str()) return tzinfo.localize(tsdt) - def formatTime(self, record, datefmt=None): + def formatTime( + self, record: logging.LogRecord, datefmt: Optional[str] = None + ) -> str: """ Method to format the timestamp for the log record """ @@ -84,22 +82,21 @@ class UcFormatter(logging.Formatter): return recdt.isoformat() -class Logger(object): +class Logger: """ Class for implementing a consistent logging format and location """ - source = None + source = '' enable_logfile = True - # pylint: disable=too-many-arguments def __init__( self, - logname=None, - level=INFO, - enable_logfile=True, - syslog_facility=logging.handlers.SysLogHandler.LOG_USER, - logpath=PLATFORM_DEFS[sys.platform]['logdir'], + logname: Optional[str] = None, + level: int = INFO, + enable_logfile: bool = True, + syslog_facility: int = logging.handlers.SysLogHandler.LOG_USER, + logpath: str = PLATFORM_DEFS[sys.platform]['logdir'], ): self.enable_logfile = enable_logfile @@ -123,9 +120,9 @@ class Logger(object): self._get_source() # Set log formatting - basefmt = '%(levelname)s {}: %(message)s'.format(self.source) + basefmt = f'%(levelname)s {self.source}: %(message)s' local_fmt = UcFormatter( - fmt='%(asctime)s {}'.format(basefmt), + fmt=f'%(asctime)s {basefmt}', datefmt='%Y-%m-%d %H:%M:%S %z', ) syslog_fmt = logging.Formatter(fmt=basefmt) @@ -139,7 +136,7 @@ class Logger(object): file_handler = logging.handlers.TimedRotatingFileHandler( os.path.join( logpath, - '{}.log'.format(os.path.splitext(self.source)[0]), + f'{os.path.splitext(self.source)[0]}.log', ), when='midnight', backupCount=90, @@ -168,7 +165,7 @@ class Logger(object): self.logger = logger - def _get_source(self): + def _get_source(self) -> None: """ Internal method to determine the calling script. @@ -199,38 +196,38 @@ class Logger(object): # Override built-in method # pylint: disable=invalid-name - def setLevel(self, level): + def setLevel(self, level: int) -> None: """ Method to set the logging level """ self.logger.setLevel(level) # FIXME: Somehow remove the redundancy below (functools.partial?) - def debug(self, *args, **kwargs): + def debug(self, *args: Any, **kwargs: Any) -> None: """ Method to log a debug level message. """ self.logger.debug(*args, **kwargs) - def info(self, *args, **kwargs): + def info(self, *args: Any, **kwargs: Any) -> None: """ Method to log an info level message. """ self.logger.info(*args, **kwargs) - def warning(self, *args, **kwargs): + def warning(self, *args: Any, **kwargs: Any) -> None: """ Method to log a warning level message. """ self.logger.warning(*args, **kwargs) - def error(self, *args, **kwargs): + def error(self, *args: Any, **kwargs: Any) -> None: """ Method to log an error level message. """ self.logger.error(*args, **kwargs) - def critical(self, *args, **kwargs): + def critical(self, *args: Any, **kwargs: Any) -> None: """ Method to log an critical level message. """ @@ -244,7 +241,7 @@ class Logger(object): if __name__ == '__main__': - def parse_args(): + def parse_args() -> argparse.Namespace: """ Function to parse the CLI arguments """ @@ -253,10 +250,10 @@ if __name__ == '__main__': group = parser.add_mutually_exclusive_group() for level in ['debug', 'info', 'warning', 'error']: group.add_argument( - '-{}'.format(level[0]), - '--{}'.format(level), + f'-{level[0]}', + f'--{level}', action='store_true', - help='log message at level {}'.format(level.upper()), + help=f'log message at level {level.upper()}', ) parser.add_argument( @@ -275,7 +272,7 @@ if __name__ == '__main__': return parser.parse_args() - def main(): + def main() -> None: """ Main entrypoint for the CLI """