Updated _logger.py

Changed module in accordance to results of pytest unit testing.

`__DEFAULT_OUT_FILE` now converts a file spec into a real pathspec to
the system. This is now considered a constant default attribute.

New attribute `__default_out_file` to take the value of
`__DEFAULT_OUT_FILE` on initial class initialisation. However, this
attribute may be changed on a new class construction, and is used by the
class itself as the default output to file when logging.

Attribute `log` is reflective of `__default_out_file` and CANNOT be
changed by the user to affect class instance, making it Read-Only.

Added new public method `new`, which can reinitialise the
Singleton instance to change the default logging file. Note, once an
instance is created, the output file cannot be changed unless `new` is
invoked with a new file pathspec. This is to guarantee integrity of
logging output to a single file, unless otherwise required.

Class modifications to address changes listed above and bug fixes
identified from unit testing.
This commit is contained in:
Ethan Smith-Coss 2022-05-12 14:03:28 +01:00
parent 61c3411faf
commit f22e6ea554
Signed by: TheOnePath
GPG Key ID: 4E7D436CE1A0BAF1

View File

@ -52,14 +52,16 @@ class Logger: # class redeclaration & initialisation
__IS_STDOUT_REDIR: bool = os.isatty(sys.stdout.fileno())
__IS_STDERR_REDIR: bool = os.isatty(sys.stderr.fileno())
## the default log out file
__DEFAULT_OUT_FILE: str = "dump.log"
__DEFAULT_OUT_FILE: str = os.path.realpath("dump.log")
## log info namedtuple for storing class states
__LOG_INFO_TUPLE = namedtuple('__LOG_INFO_TUPLE',
['isatty', 'lv', 'msg', 'sep', 'end'])
## create instance attribute for class singleton
__instance__ = None
## create default file instance which can change on construct
__default_out_file = __DEFAULT_OUT_FILE
## create instance attribute as read-only for log location
log = None
log = __default_out_file
def __new__(cls, *, out_f: Union[str, None] = None) -> Logger:
"""Construct a new instance of the class and initialise it.
@ -71,14 +73,13 @@ class Logger: # class redeclaration & initialisation
"""
if cls.__instance__ is None:
cls.__instance__ = super(Logger, cls).__new__(cls) # establish singleton instance
cls.log = cls.__DEFAULT_OUT_FILE # initialise attribute to default
## handle if a custom file pathspec was given
if out_f is not None and isinstance(out_f, str):
## verify path and convert to real pathspec.
if common.is_path_spec(out_f):
## redefine the default log out attribute and create
## public attribute for the currect log location
cls.log = cls.__DEFAULT_OUT_FILE = \
cls.log = cls.__default_out_file =\
os.path.realpath(out_f).strip('"')
cls.__loginfo: Logger.__LOG_INFO_TUPLE = Logger.__LOG_INFO_TUPLE(
@ -86,10 +87,19 @@ class Logger: # class redeclaration & initialisation
) # default the namedtuple to None on first instance
cls.printLog2File("----[New instance of script has been started]----",
file=cls.__DEFAULT_OUT_FILE, mode='w')
file=cls.log, mode='w')
return cls.__instance__
@classmethod
def new(cls, *, out_f: Union[str, None] = None) -> Logger:
cls.__instance__ = None # destroy the instance
# reset all attributes to use the default file out
cls.log = cls.__default_out_file =\
cls.__DEFAULT_OUT_FILE
return Logger(out_f=out_f) # construct new instance and return it
@classmethod
def debug(cls, *value: object, sep: Union[str, None] = None,
end: Union[str, None] = None, wrapping: bool = True,
@ -236,13 +246,13 @@ class Logger: # class redeclaration & initialisation
"""
## handle if no file parameter was given
if file is None or not isinstance(file, (TextIOWrapper, str)):
file = Logger.__DEFAULT_OUT_FILE
file = Logger.__default_out_file
if not isinstance(file, str):
file = file.name
if not os.path.exists(file):
file = Logger.__DEFAULT_OUT_FILE
file = Logger.__default_out_file
_frame = sys._getframe(2) if sys._getframe(1).f_code.co_name in \
dir(Logger) else sys._getframe(1)