Strict typing

This commit is contained in:
Scott Wallace 2021-12-11 17:10:44 +00:00
parent 5bf139a737
commit e875b65321
Signed by: scott
GPG key ID: AA742FDC5AFE2A72

View file

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