Repository: rochacbruno/dynaconf
Pull request #50 (2018-05-19 06:48:32)

Fix precedence of namespace in loaders


Patch:
diff --git a/HISTORY b/HISTORY
index 4c4515a..bcf1dcc 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3,6 +3,11 @@ Changelog
 
 These are all the changes in Dynaconf since the first public release.
 
+0.7.4
+-----
+- Fixed error in namespace precedence examples/toml_with_secrets added to test it
+- added obj.BASE_NAMESPACE_FOR_DYNACONF to be defined as the default root namespace
+
 0.7.3
 -----
 - Added AUTO_CAST_FOR_DYNACONF=off to disable the @type casters
diff --git a/Makefile b/Makefile
index ec2521b..cac4a69 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@ test_examples:
 	@cd example/flask_with_json;pwd;flask routes | grep -c flask_with_json
 	@cd example/flask_with_ini;pwd;flask routes | grep -c flask_with_ini
 	@cd example/validator/;pwd;python app.py | grep -c validator
+	@cd example/toml_with_secrets/;pwd;python program.py | grep -c My5up3r53c4et
 
 
 test_vault:
diff --git a/README.md b/README.md
index cf22aa8..d9f659b 100644
--- a/README.md
+++ b/README.md
@@ -125,7 +125,7 @@ username = 'admin'
 password = false
 ```
 
-**2 -** Create `.secrets.toml` to store sensitive variables
+**2 -** Create `.secrets.toml` to store project sensible variables
 
 ```toml
 [dynaconf]
diff --git a/dynaconf/base.py b/dynaconf/base.py
index 38405cc..a92d81e 100644
--- a/dynaconf/base.py
+++ b/dynaconf/base.py
@@ -527,9 +527,9 @@ class Settings(object):
 
     def execute_loaders(self, namespace=None, silent=None, key=None):
         """Execute all internal and registered loaders"""
-        silent = silent or self.SILENT_ERRORS_FOR_DYNACONF
         if key is None:
             default_loader(self, self._defaults)
+        silent = silent or self.SILENT_ERRORS_FOR_DYNACONF
         settings_loader(self, namespace=namespace, silent=silent, key=key)
         self.load_extra_yaml(namespace, silent, key)  # DEPRECATED
         enable_external_loaders(self)
@@ -611,6 +611,9 @@ def raw_logger():
         )
     except ImportError:  # pragma: no cover
         logger = logging.getLogger("dynaconf")
+        logging.basicConfig(
+            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
+        )
         logger.setLevel(getattr(logging, level))
         logger.debug("starting logger")
         return logger
@@ -634,3 +637,7 @@ def compat_kwargs(kwargs):
                 old, new
             )
             kwargs[new] = kwargs[old]
+
+    for key in ['NAMESPACE_FOR_DYNACONF', 'DYNACONF_NAMESPACE']:
+        if key in kwargs:
+            kwargs['BASE_NAMESPACE_FOR_DYNACONF'] = kwargs[key]
diff --git a/dynaconf/default_settings.py b/dynaconf/default_settings.py
index f1b72b2..d2d17d7 100644
--- a/dynaconf/default_settings.py
+++ b/dynaconf/default_settings.py
@@ -45,6 +45,7 @@ SETTINGS_MODULE_FOR_DYNACONF = get('SETTINGS_MODULE_FOR_DYNACONF',
 
 # Namespace for envvars
 NAMESPACE_FOR_DYNACONF = get('NAMESPACE_FOR_DYNACONF', 'DYNACONF')
+BASE_NAMESPACE_FOR_DYNACONF = get('BASE_NAMESPACE_FOR_DYNACONF', 'DYNACONF')
 
 # The env var specifying settings module
 ENVVAR_FOR_DYNACONF = get('ENVVAR_FOR_DYNACONF', 'DYNACONF_SETTINGS')
@@ -89,13 +90,13 @@ default_loaders = [
 LOADERS_FOR_DYNACONF = get('LOADERS_FOR_DYNACONF', default_loaders)
 
 # Errors in loaders should be silenced?
-SILENT_ERRORS_FOR_DYNACONF = get('SILENT_ERRORS_FOR_DYNACONF', False)
+SILENT_ERRORS_FOR_DYNACONF = get('SILENT_ERRORS_FOR_DYNACONF', True)
 
 # always fresh variables
 FRESH_VARS_FOR_DYNACONF = get('FRESH_VARS_FOR_DYNACONF', [])
 
 # debug
-DEBUG_LEVEL_FOR_DYNACONF = get('DEBUG_LEVEL_FOR_DYNACONF', 'ERROR')
+DEBUG_LEVEL_FOR_DYNACONF = get('DEBUG_LEVEL_FOR_DYNACONF', 'NOTSET')
 
 YAML = get('YAML', None)
 TOML = get('TOML', None)
diff --git a/dynaconf/loaders/__init__.py b/dynaconf/loaders/__init__.py
index a7cef20..6c09004 100644
--- a/dynaconf/loaders/__init__.py
+++ b/dynaconf/loaders/__init__.py
@@ -28,8 +28,8 @@ def default_loader(obj, defaults=None):
     # check overrides in env vars
     default_settings.start_dotenv(obj)
     for key in all_keys:
-        env_value = obj.get_env(key)
-        if env_value:
+        env_value = obj.get_env(key, '_not_found')
+        if env_value != '_not_found':
             obj.logger.debug(
                 "default_loader:overriding from envvar: %s:%s",
                 key, env_value
@@ -38,7 +38,7 @@ def default_loader(obj, defaults=None):
 
 
 def settings_loader(obj, settings_module=None, namespace=None,
-                    silent=False, key=None):
+                    silent=True, key=None):
     """Loads from defined settings module, path or yaml"""
     obj.logger.debug('executing settings_loader: %s', settings_module)
     settings_module = settings_module or obj.settings_module
@@ -87,7 +87,7 @@ def settings_loader(obj, settings_module=None, namespace=None,
         # load from default defined module if exists (never gets cleaned)
         load_from_module(obj, mod_file, key=key)
 
-        if namespace and namespace != obj.NAMESPACE_FOR_DYNACONF:
+        if namespace and namespace != obj.BASE_NAMESPACE_FOR_DYNACONF:
             if mod_file.endswith('.py'):
                 dirname = os.path.dirname(mod_file)
                 filename, extension = os.path.splitext(
diff --git a/dynaconf/loaders/env_loader.py b/dynaconf/loaders/env_loader.py
index 5324746..64b86e0 100644
--- a/dynaconf/loaders/env_loader.py
+++ b/dynaconf/loaders/env_loader.py
@@ -6,7 +6,7 @@ IDENTIFIER = 'env_loader'
 
 
 def load(obj, namespace=None, silent=True, key=None):
-    default_namespace = obj.get('NAMESPACE_FOR_DYNACONF')
+    default_namespace = obj.get('BASE_NAMESPACE_FOR_DYNACONF')
     # load all from default namespace (this never gets cleaned)
     load_from_env(
         IDENTIFIER,
@@ -16,6 +16,8 @@ def load(obj, namespace=None, silent=True, key=None):
         silent
     )
 
+    namespace = namespace or obj.current_namespace
+
     # rewrite with different namespace if provided
     if namespace and namespace != default_namespace:
         identifier = IDENTIFIER + '_' + namespace.lower()
diff --git a/dynaconf/loaders/ini_loader.py b/dynaconf/loaders/ini_loader.py
index 6c4f4db..390500e 100644
--- a/dynaconf/loaders/ini_loader.py
+++ b/dynaconf/loaders/ini_loader.py
@@ -33,9 +33,7 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     if not filename:
         return
 
-    namespace = namespace or obj.get('NAMESPACE_FOR_DYNACONF')
-
-    # clean(obj, namespace, identifier=filename)
+    namespace = namespace or obj.current_namespace
 
     # can be a filename settings.yml
     # can be a multiple fileset settings1.ini, settings2.ini etc
@@ -50,6 +48,16 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     else:  # it is already a list/tuple
         files = filename
 
+    # load
+    namespace_list = [obj.get('BASE_NAMESPACE_FOR_DYNACONF')]
+    # import ipdb; ipdb.set_trace()
+    if namespace and namespace not in namespace_list:
+        namespace_list.append(namespace)
+    load_from_ini(obj, files, namespace_list, silent, key)
+
+
+def load_from_ini(obj, files, namespaces, silent=True, key=None):
+
     for ini_file in files:
         if ini_file.endswith(INI_EXTENSIONS):  # pragma: no cover
             obj.logger.debug('Trying to load ini {}'.format(ini_file))
@@ -70,31 +78,28 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
 
         ini_data = {k.lower(): value for k, value in ini_data.items()}
 
-        # ---->
-        # Load from namespace_filename.ini
+        for namespace in namespaces:
 
-        data = {}
-        try:
-            data = ini_data[namespace.lower()]
-        except KeyError:
-            if silent:
-                obj.logger.debug(
-                    '%s namespace not defined in ini source' % namespace
-                )
+            data = {}
+            try:
+                data = ini_data[namespace.lower()]
+            except KeyError:
+                message = '%s namespace not defined in %s' % (
+                    namespace, ini_file)
+                if silent:
+                    obj.logger.warning(message)
+                else:
+                    raise KeyError(message)
+
+            if namespace != obj.get('BASE_NAMESPACE_FOR_DYNACONF'):
+                identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
             else:
-                raise KeyError(
-                    '%s namespace not defined in %s' % (namespace, filename)
-                )
-
-        if namespace and namespace != obj.get('NAMESPACE_FOR_DYNACONF'):
-            identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
-        else:
-            identifier = IDENTIFIER
+                identifier = IDENTIFIER
 
-        if not key:
-            obj.update(data, loader_identifier=identifier)
-        else:
-            obj.set(key, data.get(key), loader_identifier=identifier)
+            if not key:
+                obj.update(data, loader_identifier=identifier)
+            else:
+                obj.set(key, data.get(key), loader_identifier=identifier)
 
 
 def clean(obj, namespace, silent=True):  # noqa
diff --git a/dynaconf/loaders/json_loader.py b/dynaconf/loaders/json_loader.py
index def67ea..bf6e35d 100644
--- a/dynaconf/loaders/json_loader.py
+++ b/dynaconf/loaders/json_loader.py
@@ -19,9 +19,7 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     if not filename:
         return
 
-    namespace = namespace or obj.get('NAMESPACE_FOR_DYNACONF')
-
-    # clean(obj, namespace, identifier=filename)
+    namespace = namespace or obj.current_namespace
 
     # can be a filename settings.yml
     # can be a multiple fileset settings1.json, settings2.json etc
@@ -36,6 +34,16 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     else:  # it is already a list/tuple
         files = filename
 
+    # load
+    namespace_list = [obj.get('BASE_NAMESPACE_FOR_DYNACONF')]
+    # import ipdb; ipdb.set_trace()
+    if namespace and namespace not in namespace_list:
+        namespace_list.append(namespace)
+    load_from_json(obj, files, namespace_list, silent, key)
+
+
+def load_from_json(obj, files, namespaces, silent=True, key=None):
+
     for json_file in files:
         if json_file.endswith(JSON_EXTENSIONS):  # pragma: no cover
             obj.logger.debug('Trying to load json {}'.format(json_file))
@@ -56,31 +64,28 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
 
         json_data = {key.lower(): value for key, value in json_data.items()}
 
-        # ---->
-        # Load from namespace_filename.json
+        for namespace in namespaces:
 
-        data = {}
-        try:
-            data = json_data[namespace.lower()]
-        except KeyError:
-            if silent:
-                obj.logger.debug(
-                    '%s namespace not defined in json source' % namespace
-                )
-            else:
-                raise KeyError(
-                    '%s namespace not defined in %s' % (namespace, filename)
-                )
+            data = {}
+            try:
+                data = json_data[namespace.lower()]
+            except KeyError:
+                message = '%s namespace not defined in %s' % (
+                    namespace, json_file)
+                if silent:
+                    obj.logger.warning(message)
+                else:
+                    raise KeyError(message)
 
-        if namespace and namespace != obj.get('NAMESPACE_FOR_DYNACONF'):
-            identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
-        else:
-            identifier = IDENTIFIER
+            if namespace != obj.get('BASE_NAMESPACE_FOR_DYNACONF'):
+                identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
+            else:
+                identifier = IDENTIFIER
 
-        if not key:
-            obj.update(data, loader_identifier=identifier)
-        else:
-            obj.set(key, data.get(key), loader_identifier=identifier)
+            if not key:
+                obj.update(data, loader_identifier=identifier)
+            else:
+                obj.set(key, data.get(key), loader_identifier=identifier)
 
 
 def clean(obj, namespace, silent=True):  # noqa
diff --git a/dynaconf/loaders/redis_loader.py b/dynaconf/loaders/redis_loader.py
index 40ba6f0..4b9392d 100644
--- a/dynaconf/loaders/redis_loader.py
+++ b/dynaconf/loaders/redis_loader.py
@@ -24,7 +24,7 @@ def load(obj, namespace=None, silent=True, key=None):
     :return: None
     """
     redis = StrictRedis(**obj.get('REDIS_FOR_DYNACONF'))
-    namespace = namespace or obj.get('NAMESPACE_FOR_DYNACONF')
+    namespace = namespace or obj.current_namespace
     holder = "DYNACONF_%s" % namespace
     try:
         if key:
diff --git a/dynaconf/loaders/toml_loader.py b/dynaconf/loaders/toml_loader.py
index 16e248b..1d54bee 100644
--- a/dynaconf/loaders/toml_loader.py
+++ b/dynaconf/loaders/toml_loader.py
@@ -33,9 +33,7 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     if not filename:
         return
 
-    namespace = namespace or obj.get('NAMESPACE_FOR_DYNACONF')
-
-    # clean(obj, namespace, identifier=filename)
+    namespace = namespace or obj.current_namespace
 
     # can be a filename settings.yml
     # can be a multiple fileset settings1.toml, settings2.toml etc
@@ -50,6 +48,16 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     else:  # it is already a list/tuple
         files = filename
 
+    # load
+    namespace_list = [obj.get('BASE_NAMESPACE_FOR_DYNACONF')]
+    # import ipdb; ipdb.set_trace()
+    if namespace and namespace not in namespace_list:
+        namespace_list.append(namespace)
+    load_from_toml(obj, files, namespace_list, silent, key)
+
+
+def load_from_toml(obj, files, namespaces, silent=True, key=None):
+
     for toml_file in files:
         if toml_file.endswith(TOML_EXTENSIONS):  # pragma: no cover
             obj.logger.debug('Trying to load TOML {}'.format(toml_file))
@@ -70,31 +78,27 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
 
         toml_data = {key.lower(): value for key, value in toml_data.items()}
 
-        # ---->
-        # Load from namespace_filename.toml
-
-        data = {}
-        try:
-            data = toml_data[namespace.lower()]
-        except KeyError:
-            if silent:
-                obj.logger.debug(
-                    '%s namespace not defined in toml source' % namespace
-                )
+        for namespace in namespaces:
+            data = {}
+            try:
+                data = toml_data[namespace.lower()]
+            except KeyError:
+                message = '%s namespace not defined in %s' % (
+                    namespace, toml_file)
+                if silent:
+                    obj.logger.warning(message)
+                else:
+                    raise KeyError(message)
+
+            if namespace != obj.get('BASE_NAMESPACE_FOR_DYNACONF'):
+                identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
             else:
-                raise KeyError(
-                    '%s namespace not defined in %s' % (namespace, filename)
-                )
-
-        if namespace and namespace != obj.get('NAMESPACE_FOR_DYNACONF'):
-            identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
-        else:
-            identifier = IDENTIFIER
+                identifier = IDENTIFIER
 
-        if not key:
-            obj.update(data, loader_identifier=identifier)
-        else:
-            obj.set(key, data.get(key), loader_identifier=identifier)
+            if not key:
+                obj.update(data, loader_identifier=identifier)
+            else:
+                obj.set(key, data.get(key), loader_identifier=identifier)
 
 
 def clean(obj, namespace, silent=True):  # noqa
diff --git a/dynaconf/loaders/yaml_loader.py b/dynaconf/loaders/yaml_loader.py
index 85b5c14..871ebbe 100644
--- a/dynaconf/loaders/yaml_loader.py
+++ b/dynaconf/loaders/yaml_loader.py
@@ -33,9 +33,7 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     if not filename:
         return
 
-    namespace = namespace or obj.get('NAMESPACE_FOR_DYNACONF')
-
-    # clean(obj, namespace, identifier=filename)
+    namespace = namespace or obj.current_namespace
 
     # can be a filename settings.yml
     # can be a multiple fileset settings1.yml, settings2.yaml etc
@@ -50,6 +48,15 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
     else:  # it is already a list/tuple
         files = filename
 
+    # load
+    namespace_list = [obj.get('BASE_NAMESPACE_FOR_DYNACONF')]
+    if namespace and namespace not in namespace_list:
+        namespace_list.append(namespace)
+    load_from_yaml(obj, files, namespace_list, silent, key)
+
+
+def load_from_yaml(obj, files, namespaces, silent=True, key=None):
+
     for yaml_file in files:
         if yaml_file.endswith(YAML_EXTENSIONS):  # pragma: no cover
             try:
@@ -71,31 +78,27 @@ def load(obj, namespace=None, silent=True, key=None, filename=None):
 
         yaml_data = {key.lower(): value for key, value in yaml_data.items()}
 
-        # ---->
-        # Load from namespace_filename.yaml
-
-        data = {}
-        try:
-            data = yaml_data[namespace.lower()]
-        except KeyError:
-            if silent:
-                obj.logger.debug(
-                    '%s namespace not defined in yaml source' % namespace
-                )
+        for namespace in namespaces:
+            data = {}
+            try:
+                data = yaml_data[namespace.lower()]
+            except KeyError:
+                message = '%s namespace not defined in %s' % (
+                    namespace, yaml_file)
+                if silent:
+                    obj.logger.warning(message)
+                else:
+                    raise KeyError(message)
+
+            if namespace != obj.get('BASE_NAMESPACE_FOR_DYNACONF'):
+                identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
             else:
-                raise KeyError(
-                    '%s namespace not defined in %s' % (namespace, filename)
-                )
-
-        if namespace and namespace != obj.get('NAMESPACE_FOR_DYNACONF'):
-            identifier = "{0}_{1}".format(IDENTIFIER, namespace.lower())
-        else:
-            identifier = IDENTIFIER
+                identifier = IDENTIFIER
 
-        if not key:
-            obj.update(data, loader_identifier=identifier)
-        else:
-            obj.set(key, data.get(key), loader_identifier=identifier)
+            if not key:
+                obj.update(data, loader_identifier=identifier)
+            else:
+                obj.set(key, data.get(key), loader_identifier=identifier)
 
 
 def clean(obj, namespace, silent=True):  # noqa
diff --git a/example/toml_with_secrets/.env b/example/toml_with_secrets/.env
new file mode 100644
index 0000000..bd7e1e5
--- /dev/null
+++ b/example/toml_with_secrets/.env
@@ -0,0 +1,1 @@
+EXAMPLE_SERVER='fromenv.com'
diff --git a/example/toml_with_secrets/.secrets.toml b/example/toml_with_secrets/.secrets.toml
new file mode 100644
index 0000000..c77b04c
--- /dev/null
+++ b/example/toml_with_secrets/.secrets.toml
@@ -0,0 +1,2 @@
+[example]
+password = 'My5up3r53c4et'
diff --git a/example/toml_with_secrets/program.py b/example/toml_with_secrets/program.py
new file mode 100644
index 0000000..0a615ca
--- /dev/null
+++ b/example/toml_with_secrets/program.py
@@ -0,0 +1,6 @@
+from dynaconf import LazySettings
+settings = LazySettings(NAMESPACE_FOR_DYNACONF='example')
+
+print(settings.USERNAME)
+print(settings.SERVER)
+print(settings.PASSWORD)
diff --git a/example/toml_with_secrets/settings.toml b/example/toml_with_secrets/settings.toml
new file mode 100644
index 0000000..1d5668d
--- /dev/null
+++ b/example/toml_with_secrets/settings.toml
@@ -0,0 +1,7 @@
+[example]
+server = 'foo.com'
+username = 'admin'
+password = false
+
+[dev]
+username = 'foo'
diff --git a/setup.py b/setup.py
index a824082..c93ab6c 100644
--- a/setup.py
+++ b/setup.py
@@ -18,7 +18,7 @@ def read(*names, **kwargs):
 
 setup(
     name='dynaconf',
-    version="0.7.3",
+    version="0.7.4",
     url='https://github.com/rochacbruno/dynaconf',
     license='MIT',
     author="Bruno Rocha",


Test patch:
diff --git a/tests/test_ini_loader.py b/tests/test_ini_loader.py
index 7d6ec32..b3557bf 100644
--- a/tests/test_ini_loader.py
+++ b/tests/test_ini_loader.py
@@ -31,6 +31,7 @@ INI2 = """
 [example]
 secret = "@float 42"
 password = '@int 123456'
+host = "otheryaml.com"
 """
 
 INIS = [INI, INI2]
@@ -56,7 +57,7 @@ def test_load_from_ini():
 def test_load_from_multiple_ini():
     """Assert loads from INI string"""
     load(settings, filename=INIS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
     assert settings.SECRET == 42.0
     assert settings.PORT == 8080
@@ -66,11 +67,18 @@ def test_load_from_multiple_ini():
     assert settings.SERVICE.auth.password == 'qwerty'
     assert settings.SERVICE.auth.test == 1234
     load(settings, filename=INIS, namespace='DEVELOPMENT')
-    assert settings.HOST == 'dev_server.com'
-    assert settings.PASSWORD == 88888
+    assert settings.PORT == 8080
+    assert settings.HOST == 'otheryaml.com'
     load(settings, filename=INIS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
+    load(settings, filename=INI, namespace='DEVELOPMENT')
+    assert settings.PORT == 8080
+    assert settings.HOST == 'dev_server.com'
+    load(settings, filename=INI)
+    assert settings.HOST == 'server.com'
+    assert settings.PASSWORD == 99999
+
 
 
 def test_no_filename_is_none():
diff --git a/tests/test_json_loader.py b/tests/test_json_loader.py
index 46d5313..7339934 100644
--- a/tests/test_json_loader.py
+++ b/tests/test_json_loader.py
@@ -35,7 +35,8 @@ JSON2 = """
 {
   "example": {
     "secret": "@float 42",
-    "password": 123456
+    "password": 123456,
+    "host": "otheryaml.com"
   }
 }
 """
@@ -62,7 +63,7 @@ def test_load_from_json():
 def test_load_from_multiple_json():
     """Assert loads from JSON string"""
     load(settings, filename=JSONS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
     assert settings.SECRET == 42.0
     assert settings.PORT == 8080
@@ -72,11 +73,17 @@ def test_load_from_multiple_json():
     assert settings.SERVICE.auth.password == 'qwerty'
     assert settings.SERVICE.auth.test == 1234
     load(settings, filename=JSONS, namespace='DEVELOPMENT')
-    assert settings.HOST == 'dev_server.com'
-    assert settings.PASSWORD == 88888
+    assert settings.PORT == 8080
+    assert settings.HOST == 'otheryaml.com'
     load(settings, filename=JSONS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
+    load(settings, filename=JSON, namespace='DEVELOPMENT')
+    assert settings.PORT == 8080
+    assert settings.HOST == 'dev_server.com'
+    load(settings, filename=JSON)
+    assert settings.HOST == 'server.com'
+    assert settings.PASSWORD == 99999
 
 
 def test_no_filename_is_none():
diff --git a/tests/test_toml_loader.py b/tests/test_toml_loader.py
index 9304d63..44c1b5c 100644
--- a/tests/test_toml_loader.py
+++ b/tests/test_toml_loader.py
@@ -30,6 +30,7 @@ TOML2 = """
 [example]
 secret = "@float 42"
 password = 123456.0
+host = "otheryaml.com"
 """
 
 TOMLS = [TOML, TOML2]
@@ -54,7 +55,7 @@ def test_load_from_toml():
 def test_load_from_multiple_toml():
     """Assert loads from TOML string"""
     load(settings, filename=TOMLS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
     assert settings.SECRET == 42.0
     assert settings.PORT == 8080
@@ -64,11 +65,17 @@ def test_load_from_multiple_toml():
     assert settings.SERVICE.auth.password == 'qwerty'
     assert settings.SERVICE.auth.test == 1234
     load(settings, filename=TOMLS, namespace='DEVELOPMENT')
-    assert settings.HOST == 'dev_server.com'
-    assert settings.PASSWORD == 88888
+    assert settings.PORT == 8080
+    assert settings.HOST == 'otheryaml.com'
     load(settings, filename=TOMLS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
+    load(settings, filename=TOML, namespace='DEVELOPMENT')
+    assert settings.PORT == 8080
+    assert settings.HOST == 'dev_server.com'
+    load(settings, filename=TOML)
+    assert settings.HOST == 'server.com'
+    assert settings.PASSWORD == 99999
 
 
 def test_no_filename_is_none():
diff --git a/tests/test_yaml_loader.py b/tests/test_yaml_loader.py
index c3415f0..b37019b 100644
--- a/tests/test_yaml_loader.py
+++ b/tests/test_yaml_loader.py
@@ -30,6 +30,7 @@ example:
   # @float casting not needed, used only for testing
   secret: '@float 42'
   password: 123456
+  host: otheryaml.com
 """
 
 YAMLS = [YAML, YAML2]
@@ -54,7 +55,7 @@ def test_load_from_yaml():
 def test_load_from_multiple_yaml():
     """Assert loads from YAML string"""
     load(settings, filename=YAMLS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
     assert settings.SECRET == 42.0
     assert settings.PORT == 8080
@@ -64,12 +65,17 @@ def test_load_from_multiple_yaml():
     assert settings.SERVICE.auth.password == 'qwerty'
     assert settings.SERVICE.auth.test == 1234
     load(settings, filename=YAMLS, namespace='DEVELOPMENT')
-    assert settings.HOST == 'dev_server.com'
-    assert settings.PASSWORD == 88888
+    assert settings.PORT == 8080
+    assert settings.HOST == 'otheryaml.com'
     load(settings, filename=YAMLS)
-    assert settings.HOST == 'server.com'
+    assert settings.HOST == 'otheryaml.com'
     assert settings.PASSWORD == 123456
-
+    load(settings, filename=YAML, namespace='DEVELOPMENT')
+    assert settings.PORT == 8080
+    assert settings.HOST == 'dev_server.com'
+    load(settings, filename=YAML)
+    assert settings.HOST == 'server.com'
+    assert settings.PASSWORD == 99999
 
 def test_no_filename_is_none():
     """Assert if passed no filename return is None"""