Repository: scoutapp/scout_apm_python
Pull request #447 (2020-01-03 15:56:00)

Simplify Config classes
* Remove `name()` method and instead just use the class names, which have been shortened since they're namespaced enough.
* Remove unnecessary `global` declarations, since we're only mutating the internal state of `SCOUT_PYTHON_VALUES`.


Patch:
diff --git a/src/scout_apm/core/config.py b/src/scout_apm/core/config.py
index e3bdcf3..ab7acd8 100644
--- a/src/scout_apm/core/config.py
+++ b/src/scout_apm/core/config.py
@@ -21,11 +21,11 @@ class ScoutConfig(object):
 
     def __init__(self):
         self.layers = [
-            ScoutConfigEnv(),
-            ScoutConfigPython(),
-            ScoutConfigDerived(self),
-            ScoutConfigDefaults(),
-            ScoutConfigNull(),
+            Env(),
+            Python(),
+            Derived(self),
+            Defaults(),
+            Null(),
         ]
 
     def value(self, key):
@@ -39,15 +39,16 @@ class ScoutConfig(object):
             if layer.has_config(key):
                 return layer
 
-        # Should be unreachable because ScoutConfigNull returns None for all
-        # keys.
+        # Should be unreachable because Null returns None for all keys.
         raise ValueError("key {!r} not found in any layer".format(key))
 
     def log(self):
         logger.debug("Configuration Loaded:")
         for key in self.known_keys():
             layer = self.locate_layer_for_key(key)
-            logger.debug("%-9s: %s = %s", layer.name(), key, layer.value(key))
+            logger.debug(
+                "%-9s: %s = %s", layer.__class__.__name__, key, layer.value(key)
+            )
 
     def known_keys(self):
         return [
@@ -89,7 +90,6 @@ class ScoutConfig(object):
         Sets a configuration value for the Scout agent. Values set here will
         not override values set in ENV.
         """
-        global SCOUT_PYTHON_VALUES
         for key, value in kwargs.items():
             SCOUT_PYTHON_VALUES[key] = value
 
@@ -98,7 +98,6 @@ class ScoutConfig(object):
         """
         Removes a configuration value for the Scout agent.
         """
-        global SCOUT_PYTHON_VALUES
         for key in keys:
             SCOUT_PYTHON_VALUES.pop(key, None)
 
@@ -109,7 +108,6 @@ class ScoutConfig(object):
 
         This is meant for use in testing.
         """
-        global SCOUT_PYTHON_VALUES
         SCOUT_PYTHON_VALUES.clear()
 
 
@@ -117,14 +115,11 @@ class ScoutConfig(object):
 SCOUT_PYTHON_VALUES = {}
 
 
-class ScoutConfigPython(object):
+class Python(object):
     """
     A configuration overlay that lets other parts of python set values.
     """
 
-    def name(self):
-        return "Python"
-
     def has_config(self, key):
         return key in SCOUT_PYTHON_VALUES
 
@@ -132,7 +127,7 @@ class ScoutConfigPython(object):
         return SCOUT_PYTHON_VALUES[key]
 
 
-class ScoutConfigEnv(object):
+class Env(object):
     """
     Reads configuration from environment by prefixing the key
     requested with "SCOUT_"
@@ -141,9 +136,6 @@ class ScoutConfigEnv(object):
     environment variable
     """
 
-    def name(self):
-        return "ENV"
-
     def has_config(self, key):
         env_key = self.modify_key(key)
         return env_key in os.environ
@@ -157,7 +149,7 @@ class ScoutConfigEnv(object):
         return env_key
 
 
-class ScoutConfigDerived(object):
+class Derived(object):
     """
     A configuration overlay that calculates from other values.
     """
@@ -169,9 +161,6 @@ class ScoutConfigDerived(object):
         """
         self.config = config
 
-    def name(self):
-        return "Derived"
-
     def has_config(self, key):
         return self.lookup_func(key) is not None
 
@@ -205,14 +194,11 @@ class ScoutConfigDerived(object):
         return platform_detection.get_triple()
 
 
-class ScoutConfigDefaults(object):
+class Defaults(object):
     """
     Provides default values for important configurations
     """
 
-    def name(self):
-        return "Defaults"
-
     def __init__(self):
         self.defaults = {
             "app_server": "",
@@ -238,7 +224,7 @@ class ScoutConfigDefaults(object):
 
     def _git_revision_sha(self):
         # N.B. The environment variable SCOUT_REVISION_SHA may also be used,
-        # but that will be picked up by ScoutConfigEnv
+        # but that will be picked up by Env
         return os.environ.get("HEROKU_SLUG_COMMIT", "")
 
     def has_config(self, key):
@@ -248,17 +234,13 @@ class ScoutConfigDefaults(object):
         return self.defaults[key]
 
 
-# Always returns None to any key
-class ScoutConfigNull(object):
+class Null(object):
     """
     Always answers that a key is present, but the value is None
 
     Used as the last step of the layered configuration.
     """
 
-    def name(self):
-        return "Null"
-
     def has_config(self, key):
         return True
 


Test patch:
diff --git a/tests/unit/core/test_config.py b/tests/unit/core/test_config.py
index a4244e7..f53352d 100644
--- a/tests/unit/core/test_config.py
+++ b/tests/unit/core/test_config.py
@@ -8,7 +8,7 @@ import sys
 
 import pytest
 
-from scout_apm.core.config import ScoutConfig, ScoutConfigNull, scout_config
+from scout_apm.core.config import Null, ScoutConfig, scout_config
 from tests.compat import mock
 
 
@@ -97,7 +97,7 @@ def test_get_undefined_config_value():
 def test_get_undefined_config_value_null_layer_removed():
     # For coverage
     config = ScoutConfig()
-    config.layers = [x for x in config.layers if not isinstance(x, ScoutConfigNull)]
+    config.layers = [x for x in config.layers if not isinstance(x, Null)]
 
     with pytest.raises(ValueError) as excinfo:
         config.value("unknown value")
@@ -162,11 +162,6 @@ def test_core_agent_permissions_invalid_uses_default():
         ScoutConfig.reset_all()
 
 
-def test_null_config_name():
-    # For coverage... this is never called elsewhere.
-    ScoutConfigNull().name()
-
-
 def test_boolean_conversion_from_env():
     config = ScoutConfig()
     with mock.patch.dict(os.environ, {"SCOUT_MONITOR": "True"}):