Repository: open-telemetry/opentelemetry-python

Issue:
Fix several configuration issues
Fix the pending issues in #563 as pointed out by @mauriciovasquezbernal. 


Discussion:

Resolving patch:
diff --git a/opentelemetry-api/src/opentelemetry/configuration/__init__.py b/opentelemetry-api/src/opentelemetry/configuration/__init__.py
--- a/opentelemetry-api/src/opentelemetry/configuration/__init__.py
+++ b/opentelemetry-api/src/opentelemetry/configuration/__init__.py
@@ -19,27 +19,27 @@
 Simple configuration manager
 
 This is a configuration manager for OpenTelemetry. It reads configuration
-values from environment variables prefixed with
-``OPENTELEMETRY_PYTHON_`` whose characters are only all caps and underscores.
-The first character after ``OPENTELEMETRY_PYTHON_`` must be an uppercase
-character.
+values from environment variables prefixed with ``OPENTELEMETRY_PYTHON_`` whose
+characters are only alphanumeric characters and unserscores, except for the
+first character after ``OPENTELEMETRY_PYTHON_`` which must not be a number.
 
 For example, these environment variables will be read:
 
 1. ``OPENTELEMETRY_PYTHON_SOMETHING``
 2. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_``
 3. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND__ELSE``
+4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else``
+4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else2``
 
 These won't:
 
 1. ``OPENTELEMETRY_PYTH_SOMETHING``
-2. ``OPENTELEMETRY_PYTHON_something``
-3. ``OPENTELEMETRY_PYTHON_SOMETHING_2_AND__ELSE``
-4. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE``
+2. ``OPENTELEMETRY_PYTHON_2_SOMETHING_AND__ELSE``
+3. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE``
 
 The values stored in the environment variables can be found in an instance of
 ``opentelemetry.configuration.Configuration``. This class can be instantiated
-freely because instantiating it returns a singleton.
+freely because instantiating it returns always the same object.
 
 For example, if the environment variable
 ``OPENTELEMETRY_PYTHON_METER_PROVIDER`` value is ``my_meter_provider``, then
@@ -93,11 +93,13 @@ def __new__(cls) -> "Configuration":
 
             for key, value in environ.items():
 
-                match = fullmatch("OPENTELEMETRY_PYTHON_([A-Z][A-Z_]*)", key)
+                match = fullmatch(
+                    r"OPENTELEMETRY_PYTHON_([A-Za-z_][\w_]*)", key
+                )
 
                 if match is not None:
 
-                    key = match.group(1).lower()
+                    key = match.group(1)
 
                     setattr(Configuration, "_{}".format(key), value)
                     setattr(


Test patch:
diff --git a/opentelemetry-api/tests/configuration/test_configuration.py b/opentelemetry-api/tests/configuration/test_configuration.py
--- a/opentelemetry-api/tests/configuration/test_configuration.py
+++ b/opentelemetry-api/tests/configuration/test_configuration.py
@@ -21,6 +21,9 @@
 
 class TestConfiguration(TestCase):
     def setUp(self):
+        # This is added here to force a reload of the whole Configuration
+        # class, resetting its internal attributes so that each tests starts
+        # with a clean class.
         from opentelemetry.configuration import Configuration  # type: ignore
 
     def tearDown(self):
@@ -35,15 +38,25 @@ def test_singleton(self):
         {
             "OPENTELEMETRY_PYTHON_METER_PROVIDER": "meter_provider",
             "OPENTELEMETRY_PYTHON_TRACER_PROVIDER": "tracer_provider",
+            "OPENTELEMETRY_PYTHON_OThER": "other",
+            "OPENTELEMETRY_PYTHON_OTHER_7": "other_7",
+            "OPENTELEMETRY_PTHON_TRACEX_PROVIDER": "tracex_provider",
         },
     )
     def test_environment_variables(self):  # type: ignore
         self.assertEqual(
-            Configuration().meter_provider, "meter_provider"
+            Configuration().METER_PROVIDER, "meter_provider"
         )  # pylint: disable=no-member
         self.assertEqual(
-            Configuration().tracer_provider, "tracer_provider"
+            Configuration().TRACER_PROVIDER, "tracer_provider"
         )  # pylint: disable=no-member
+        self.assertEqual(
+            Configuration().OThER, "other"
+        )  # pylint: disable=no-member
+        self.assertEqual(
+            Configuration().OTHER_7, "other_7"
+        )  # pylint: disable=no-member
+        self.assertIsNone(Configuration().TRACEX_PROVIDER)
 
     @patch.dict(
         "os.environ",  # type: ignore
@@ -51,11 +64,11 @@ def test_environment_variables(self):  # type: ignore
     )
     def test_property(self):
         with self.assertRaises(AttributeError):
-            Configuration().tracer_provider = "new_tracer_provider"
+            Configuration().TRACER_PROVIDER = "new_tracer_provider"
 
     def test_slots(self):
         with self.assertRaises(AttributeError):
-            Configuration().xyz = "xyz"  # pylint: disable=assigning-non-slot
+            Configuration().XYZ = "xyz"  # pylint: disable=assigning-non-slot
 
     def test_getattr(self):
-        Configuration().xyz is None
+        self.assertIsNone(Configuration().XYZ)