From dda3ae3f54b44f4ee3627e11992ac8970a94d4e9 Mon Sep 17 00:00:00 2001
From: Brandon Rodriguez <brodriguez8774@gmail.com>
Date: Sun, 1 Nov 2020 23:08:47 -0500
Subject: [PATCH] Correct logging bug where new levels ignored overriding of
 level_num

---
 logging.py                              | 22 +++++++++++++++-------
 tests/src/logging.py                    | 22 +++++++++++++++-------
 tests/src/submodule_test/src/logging.py | 20 ++++++++++++++------
 3 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/logging.py b/logging.py
index a330164..4cd36e5 100644
--- a/logging.py
+++ b/logging.py
@@ -120,7 +120,7 @@ def init_logging(caller):
             print('Creating logging folders.')
             logging_directory.mkdir()
 
-        # Add new logging levels.
+        # Add new logging levels here.
 
         # Load dictionary of settings into logger.
         this.settings = get_logging_settings()
@@ -134,9 +134,9 @@ def init_logging(caller):
 
 def add_logging_level(level_name, level_num, method_name=None):
     """
-    Logic to add a new logging level to logger.
+    Adds a new logging level to logger.
 
-    Logic from https://stackoverflow.com/a/35804945
+    Original logic from https://stackoverflow.com/a/35804945
     :param level_name: The name of new log level to create.
     :param level_num: The numerical value of new log level to create.
     :param method_name: The name of invoke method for new log level. Defaults to lowercase of level_name.
@@ -146,16 +146,24 @@ def add_logging_level(level_name, level_num, method_name=None):
         method_name = level_name.lower()
 
     # Check if values have already been defined in logger. Prevents accidental overriding.
+    orig_log_level_name = logging.getLevelName(level_num)
     if (hasattr(logging, level_name) and
         hasattr(logging, method_name) and
-        hasattr(logging.getLoggerClass(), method_name)):
+        hasattr(logging.getLoggerClass(), method_name) and
+        orig_log_level_name == level_name
+    ):
         # Log level already set with same values. Skip setting.
         return None
     elif (hasattr(logging, level_name) or
-        hasattr(logging, method_name) or
-        hasattr(logging.getLoggerClass(), method_name)):
+          hasattr(logging, method_name) or
+          hasattr(logging.getLoggerClass(), method_name) or
+          orig_log_level_name != 'Level {0}'.format(level_num)
+    ):
         # Log level partially defined with some values. Raise error.
-        raise AttributeError('{0} already defined in logging module, but values do not match.'.format(level_name))
+        raise AttributeError('Level "{0}: {1}" already defined in logging module, but values do not match.'.format(
+            level_num,
+            level_name,
+        ))
 
     # Methods to enable logging at new level.
     def log_for_level(self, message, *args, **kwargs):
diff --git a/tests/src/logging.py b/tests/src/logging.py
index bc82d0f..345cbbf 100644
--- a/tests/src/logging.py
+++ b/tests/src/logging.py
@@ -128,7 +128,7 @@ def init_logging(caller):
             print('Creating logging folders.')
             logging_directory.mkdir()
 
-        # Add new logging levels.
+        # Add new logging levels here.
         add_logging_level('TESTING', 25)
 
         # Load dictionary of settings into logger.
@@ -143,9 +143,9 @@ def init_logging(caller):
 
 def add_logging_level(level_name, level_num, method_name=None):
     """
-    Logic to add a new logging level to logger.
+    Adds a new logging level to logger.
 
-    Logic from https://stackoverflow.com/a/35804945
+    Original logic from https://stackoverflow.com/a/35804945
     :param level_name: The name of new log level to create.
     :param level_num: The numerical value of new log level to create.
     :param method_name: The name of invoke method for new log level. Defaults to lowercase of level_name.
@@ -155,16 +155,24 @@ def add_logging_level(level_name, level_num, method_name=None):
         method_name = level_name.lower()
 
     # Check if values have already been defined in logger. Prevents accidental overriding.
+    orig_log_level_name = logging.getLevelName(level_num)
     if (hasattr(logging, level_name) and
         hasattr(logging, method_name) and
-        hasattr(logging.getLoggerClass(), method_name)):
+        hasattr(logging.getLoggerClass(), method_name) and
+        orig_log_level_name == level_name
+    ):
         # Log level already set with same values. Skip setting.
         return None
     elif (hasattr(logging, level_name) or
-        hasattr(logging, method_name) or
-        hasattr(logging.getLoggerClass(), method_name)):
+          hasattr(logging, method_name) or
+          hasattr(logging.getLoggerClass(), method_name) or
+          orig_log_level_name != 'Level {0}'.format(level_num)
+    ):
         # Log level partially defined with some values. Raise error.
-        raise AttributeError('{0} already defined in logging module, but values do not match.'.format(level_name))
+        raise AttributeError('Level "{0}: {1}" already defined in logging module, but values do not match.'.format(
+            level_num,
+            level_name,
+        ))
 
     # Methods to enable logging at new level.
     def log_for_level(self, message, *args, **kwargs):
diff --git a/tests/src/submodule_test/src/logging.py b/tests/src/submodule_test/src/logging.py
index efe6f78..3c107bb 100644
--- a/tests/src/submodule_test/src/logging.py
+++ b/tests/src/submodule_test/src/logging.py
@@ -128,7 +128,7 @@ def init_logging(caller):
             print('Creating logging folders.')
             logging_directory.mkdir()
 
-        # Add new logging levels.
+        # Add new logging levels here.
         add_logging_level('SUBMODULE', 26)
 
         # Load dictionary of settings into logger.
@@ -143,9 +143,9 @@ def init_logging(caller):
 
 def add_logging_level(level_name, level_num, method_name=None):
     """
-    Logic to add a new logging level to logger.
+    Adds a new logging level to logger.
 
-    Logic from https://stackoverflow.com/a/35804945
+    Original logic from https://stackoverflow.com/a/35804945
     :param level_name: The name of new log level to create.
     :param level_num: The numerical value of new log level to create.
     :param method_name: The name of invoke method for new log level. Defaults to lowercase of level_name.
@@ -155,16 +155,24 @@ def add_logging_level(level_name, level_num, method_name=None):
         method_name = level_name.lower()
 
     # Check if values have already been defined in logger. Prevents accidental overriding.
+    orig_log_level_name = logging.getLevelName(level_num)
     if (hasattr(logging, level_name) and
         hasattr(logging, method_name) and
-        hasattr(logging.getLoggerClass(), method_name)):
+        hasattr(logging.getLoggerClass(), method_name) and
+        orig_log_level_name == level_name
+    ):
         # Log level already set with same values. Skip setting.
         return None
     elif (hasattr(logging, level_name) or
         hasattr(logging, method_name) or
-        hasattr(logging.getLoggerClass(), method_name)):
+        hasattr(logging.getLoggerClass(), method_name) or
+        orig_log_level_name != 'Level {0}'.format(level_num)
+    ):
         # Log level partially defined with some values. Raise error.
-        raise AttributeError('{0} already defined in logging module, but values do not match.'.format(level_name))
+        raise AttributeError('Level "{0}: {1}" already defined in logging module, but values do not match.'.format(
+            level_num,
+            level_name,
+        ))
 
     # Methods to enable logging at new level.
     def log_for_level(self, message, *args, **kwargs):
-- 
GitLab